mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
fix(v3): overhaul drag-and-drop for Linux reliability and simplify Windows implementation (#4848)
* fix(v3): overhaul drag-and-drop for Linux reliability and simplify Windows This commit fixes drag-and-drop reliability on Linux and simplifies the Windows implementation. ## Linux - Rewrite GTK drag handlers to properly intercept external file drops - Fix HTML5 internal drag-and-drop being broken when file drop enabled - Add hover effects during file drag operations - Fix multiple app instances interfering with each other ## Windows - Remove native IDropTarget in favor of JavaScript approach (matches v2) - File drops now handled via chrome.webview.postMessageWithAdditionalObjects ## All Platforms - Rename EnableDragAndDrop to EnableFileDrop - Rename data-wails-drop-target to data-file-drop-target - Rename wails-drop-target-active to file-drop-target-active - Add comprehensive drag-and-drop documentation ## Breaking Changes - EnableDragAndDrop -> EnableFileDrop - data-wails-dropzone -> data-file-drop-target - wails-dropzone-hover -> file-drop-target-active - DropZoneDetails -> DropTargetDetails - Remove WindowDropZoneFilesDropped event (use WindowFilesDropped) * feat(macos): optimize drag event performance with debouncing and caching - Add 50ms debouncing to limit drag events to 20/sec (was 120/sec) - Implement window implementation caching to avoid repeated lookups - Maintain existing 5-pixel threshold for immediate response - Keep zero-allocation path with pre-allocated buffers - Rename linuxDragActive to nativeDragActive for clarity - Update IMPLEMENTATION.md with optimization details and Windows guidance Performance improvements: - 83% reduction in event frequency - ~6x reduction in CPU/memory usage during drag operations - Maintains smooth visual feedback with InvokeSync for timer callbacks * fix(windows): implement proper file drop support for Windows - Remove incorrect AllowExternalDrag(false) call that was blocking file drops - Fix message prefix from 'FilesDropped' to 'file:drop:' to match JS runtime - Fix coordinate parsing for 'file:drop:x:y' format (indices 2,3 not 1,2) - Add enableFileDrop flag injection to JS runtime during navigation - Update JS runtime to check enableFileDrop flag before processing drops - Always call preventDefault() to stop browser navigation on file drags - Show 'no drop' cursor when file drops are disabled - Update example to filter file drags from HTML drop zone handlers - Add documentation for combining file drop with HTML drag-and-drop * fix(v3): block file drops on Linux when EnableFileDrop is false - Add disableDND() to intercept and reject external file drags at GTK level - Show 'no drop' cursor when files are dragged over window - Allow internal HTML5 drag-and-drop to work normally - Initialize _wails.flags object in runtime core to prevent undefined errors - Inject enableFileDrop flag on Linux and macOS (matching Windows) - Fix bare _wails reference to use window._wails - Update docs with info about blocked drops and combining with HTML DnD * fix(darwin): add missing fmt import in webview_window_darwin.go * fix(macOS): implement hover effects for file drag-and-drop with optimizations - Added draggingUpdated: handler to track mouse movement during drag operations - Implemented macosOnDragEnter/Exit/Over export functions for real-time hover state - Fixed JS function call from '_wails.handlePlatformFileDrop' to correct 'wails.Window.HandlePlatformFileDrop' - Added EnableFileDrop flag checks to prevent hover effects when file drops are disabled - Renamed linuxDragActive to nativeDragActive for cross-platform consistency Performance optimizations: - Added 50ms debounce to reduce event frequency from ~120/sec to ~20/sec - Implemented 5-pixel movement threshold for immediate response - Added window caching with sync.Map to avoid repeated lookups - Zero-allocation JavaScript calls with pre-allocated 128-byte buffer - Reduced memory usage to ~18 bytes per event (6x reduction) Build improvements: - Updated runtime Taskfile to include documentation generation - Added docs:build task to runtime build process - Fixed build order: events → docs → runtime Documentation: - Added IMPLEMENTATION.md with optimization details - Included guidance for Windows implementation * chore(v3/examples): remove html-dnd-api example The drag-n-drop example now demonstrates both external file drops and internal HTML5 drag-and-drop, making this separate example redundant. * docs(v3): move drag-and-drop implementation details to runtime-internals - Add drag-and-drop section to contributing/runtime-internals.mdx - Remove IMPLEMENTATION.md from example (content now in proper docs) - Covers platform differences, debugging tips, and key files * fix(v3): remove html-dnd-api from example build list * fix(v3): remove duplicate json import in application_darwin.go * fix(v3): address CodeRabbit review feedback - Fix docs to use app.Window.NewWithOptions() instead of deprecated API - Add mutex protection to dragOverJSBuffer to prevent race conditions - Add mutex protection to dragThrottleState fields for thread safety * docs: add coderabbit pre-push requirement to AGENTS.md * fix(v3/test): use correct CSS class name file-drop-target-active * chore(v3/test): remove dnd-test directory This was a development test file that shouldn't be in the PR. The drag-n-drop example serves as the proper test case. * docs(v3): update Windows file drop comment to reflect implemented fix Remove stale TODO - enableFileDrop flag is now injected in navigationCompleted * refactor(v3): make handleDragAndDropMessage unexported Internal method only called by application event loop, not part of public API.
This commit is contained in:
parent
53cd30acc7
commit
53c2275fea
47 changed files with 3317 additions and 2201 deletions
|
|
@ -135,6 +135,7 @@ For example: `bd create --help` shows `--parent`, `--deps`, `--assignee`, etc.
|
|||
- Check `bd ready` before asking "what should I work on?"
|
||||
- Store AI planning docs in `history/` directory
|
||||
- Run `bd <cmd> --help` to discover available flags
|
||||
- **ALWAYS run `coderabbit --plain` before committing** to get code analysis and catch issues early
|
||||
- Do NOT create markdown TODO lists
|
||||
- Do NOT use external issue trackers
|
||||
- Do NOT duplicate tracking systems
|
||||
|
|
|
|||
|
|
@ -171,7 +171,11 @@ export default defineConfig({
|
|||
collapsed: true,
|
||||
autogenerate: { directory: "features/browser" },
|
||||
},
|
||||
{ label: "Drag & Drop", link: "/features/drag-drop" },
|
||||
{
|
||||
label: "Drag & Drop",
|
||||
collapsed: true,
|
||||
autogenerate: { directory: "features/drag-and-drop" },
|
||||
},
|
||||
{
|
||||
label: "Keyboard",
|
||||
collapsed: true,
|
||||
|
|
|
|||
|
|
@ -170,6 +170,80 @@ Follow this checklist and you'll keep the cross-platform contract intact.
|
|||
|
||||
---
|
||||
|
||||
## 9. Drag-and-Drop
|
||||
|
||||
File drag-and-drop uses a **JavaScript-first approach** on all platforms. The native layer intercepts OS drag events, but the actual drop handling and DOM interaction happens in JavaScript.
|
||||
|
||||
### Flow
|
||||
|
||||
1. User drags files from OS over the Wails window
|
||||
2. Native layer detects the drag and notifies JavaScript for hover effects
|
||||
3. User drops files
|
||||
4. Native layer sends file paths + coordinates to JavaScript
|
||||
5. JavaScript finds the drop target element (`data-file-drop-target`)
|
||||
6. JavaScript sends file paths + element details to Go backend
|
||||
7. Go emits `WindowFilesDropped` event with full context
|
||||
|
||||
### Platform Implementations
|
||||
|
||||
| Platform | Native Layer | Key Challenge |
|
||||
|----------|--------------|---------------|
|
||||
| **Windows** | WebView2's built-in drag support | Coordinates in CSS pixels, no conversion needed |
|
||||
| **macOS** | NSWindow drag delegates | Convert window-relative to webview-relative coords |
|
||||
| **Linux** | GTK3 drag signals | Must distinguish file drags from internal HTML5 drags |
|
||||
|
||||
### Linux: Distinguishing Drag Types
|
||||
|
||||
GTK and WebKit both want to handle drag events. The key is checking the drag target type:
|
||||
|
||||
```c
|
||||
static gboolean is_file_drag(GdkDragContext *context) {
|
||||
GList *targets = gdk_drag_context_list_targets(context);
|
||||
for (GList *l = targets; l != NULL; l = l->next) {
|
||||
GdkAtom atom = GDK_POINTER_TO_ATOM(l->data);
|
||||
gchar *name = gdk_atom_name(atom);
|
||||
if (name && g_strcmp0(name, "text/uri-list") == 0) {
|
||||
g_free(name);
|
||||
return TRUE; // External file drag
|
||||
}
|
||||
g_free(name);
|
||||
}
|
||||
return FALSE; // Internal HTML5 drag
|
||||
}
|
||||
```
|
||||
|
||||
Signal handlers return `FALSE` for internal drags (letting WebKit handle them) and `TRUE` for file drags (handling them ourselves).
|
||||
|
||||
### Blocking File Drops
|
||||
|
||||
When `EnableFileDrop` is `false`, we still need to prevent the browser from navigating to dropped files. Each platform handles this differently:
|
||||
|
||||
- **Windows**: JavaScript calls `preventDefault()` on drag events
|
||||
- **macOS**: JavaScript calls `preventDefault()` on drag events
|
||||
- **Linux**: GTK signal handlers intercept and reject file drags at the native level
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `pkg/application/linux_cgo.go` | GTK drag signal handlers (C code in cgo preamble) |
|
||||
| `pkg/application/webview_window_darwin.go` | macOS drag delegates |
|
||||
| `pkg/application/webview_window_windows.go` | WebView2 message handling |
|
||||
| `internal/runtime/desktop/@wailsio/runtime/src/window.ts` | JavaScript drop handling |
|
||||
|
||||
### Debugging
|
||||
|
||||
- **Linux**: Add `printf` in C code (remember `fflush(stdout)`)
|
||||
- **Windows**: Use `globalApplication.debug()`
|
||||
- **JavaScript**: Check browser console, enable debug mode
|
||||
|
||||
Common issues:
|
||||
1. **Internal HTML5 drag not working**: Native handler intercepting it (return `FALSE` for non-file drags)
|
||||
2. **Hover effects not showing**: JavaScript handlers not being called
|
||||
3. **Wrong coordinates**: Check coordinate space conversions
|
||||
|
||||
---
|
||||
|
||||
You now have a guided tour of the runtime internals. Combine this knowledge with
|
||||
the **Codebase Layout** map and the **Asset Server** docs to navigate confidently
|
||||
and make impactful contributions. Happy coding!
|
||||
|
|
|
|||
212
docs/src/content/docs/features/drag-and-drop/files.mdx
Normal file
212
docs/src/content/docs/features/drag-and-drop/files.mdx
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
---
|
||||
title: File Drop
|
||||
description: Accept files dragged from the operating system into your application
|
||||
sidebar:
|
||||
order: 1
|
||||
---
|
||||
|
||||
Wails lets users drag files from the operating system (file manager, desktop) into your application. Unlike HTML5 drag-and-drop which only works within the browser, this gives you access to actual file paths on disk.
|
||||
|
||||
## Enable File Drop
|
||||
|
||||
File drop is disabled by default. To enable it, set `EnableFileDrop: true` in your window options:
|
||||
|
||||
```go
|
||||
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "My App",
|
||||
Width: 800,
|
||||
Height: 600,
|
||||
EnableFileDrop: true,
|
||||
})
|
||||
```
|
||||
|
||||
When `EnableFileDrop` is `false` (the default), files dragged from the OS are blocked - they won't open in the webview or trigger any events. This prevents accidental navigation when users drag files over your app.
|
||||
|
||||
## Define Drop Zones
|
||||
|
||||
Drop zones tell Wails which elements should accept files. Files dropped outside a drop zone are ignored.
|
||||
|
||||
Add the `data-file-drop-target` attribute to any element:
|
||||
|
||||
```html
|
||||
<div id="upload" class="drop-zone" data-file-drop-target>
|
||||
Drop files here
|
||||
</div>
|
||||
```
|
||||
|
||||
You can have multiple drop zones. The element's `id` and CSS classes are passed to your Go code, so you can handle drops differently depending on where files land.
|
||||
|
||||
## Style Drag Hover
|
||||
|
||||
When files are dragged over a drop zone, Wails adds the `file-drop-target-active` class. This lets you provide visual feedback so users know where they can drop:
|
||||
|
||||
```css
|
||||
.drop-zone {
|
||||
border: 2px dashed #ccc;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.drop-zone.file-drop-target-active {
|
||||
border-color: #007bff;
|
||||
background-color: rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
The class is removed automatically when files leave the zone or are dropped.
|
||||
|
||||
## Detect Dropped Files
|
||||
|
||||
When files are dropped on a valid drop zone, Wails fires a `WindowFilesDropped` event. The event context contains the full filesystem paths of all dropped files:
|
||||
|
||||
```go
|
||||
import "github.com/wailsapp/wails/v3/pkg/events"
|
||||
|
||||
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
|
||||
for _, file := range files {
|
||||
fmt.Println("Dropped:", file)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The paths are absolute, like `/home/user/documents/report.pdf` or `C:\Users\Name\Documents\report.pdf`.
|
||||
|
||||
## Get Drop Target Info
|
||||
|
||||
When you have multiple drop zones, you can find out which one received the files using `DropTargetDetails()`:
|
||||
|
||||
```go
|
||||
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
details := event.Context().DropTargetDetails()
|
||||
|
||||
fmt.Printf("Dropped on element: id=%s, classes=%v\n",
|
||||
details.ElementID, details.ClassList)
|
||||
fmt.Printf("Position: x=%d, y=%d\n", details.X, details.Y)
|
||||
})
|
||||
```
|
||||
|
||||
This lets you route files to different handlers:
|
||||
|
||||
```go
|
||||
switch details.ElementID {
|
||||
case "images":
|
||||
handleImageUpload(files)
|
||||
case "documents":
|
||||
handleDocumentUpload(files)
|
||||
}
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
**Go:**
|
||||
|
||||
```go
|
||||
window := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "File Uploader",
|
||||
EnableFileDrop: true,
|
||||
})
|
||||
|
||||
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
details := event.Context().DropTargetDetails()
|
||||
|
||||
// Send to frontend
|
||||
app.EmitEvent("files-dropped", map[string]any{
|
||||
"files": files,
|
||||
"target": details.ElementID,
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
**HTML:**
|
||||
|
||||
```html
|
||||
<div id="images" class="drop-zone" data-file-drop-target>
|
||||
Drop images here
|
||||
</div>
|
||||
|
||||
<div id="documents" class="drop-zone" data-file-drop-target>
|
||||
Drop documents here
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.drop-zone {
|
||||
border: 2px dashed #ccc;
|
||||
border-radius: 8px;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
margin: 20px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.drop-zone.file-drop-target-active {
|
||||
border-color: #007bff;
|
||||
background-color: rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Full Window Drop
|
||||
|
||||
If you want files to be droppable anywhere in your app, add the attribute to the body element:
|
||||
|
||||
```html
|
||||
<body data-file-drop-target>
|
||||
<!-- Your app content -->
|
||||
</body>
|
||||
```
|
||||
|
||||
You can use a CSS overlay to indicate the entire window is a drop target:
|
||||
|
||||
```css
|
||||
body.file-drop-target-active::after {
|
||||
content: "Drop files anywhere";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
color: #007bff;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
pointer-events: none;
|
||||
}
|
||||
```
|
||||
|
||||
## Combining with HTML Drag & Drop
|
||||
|
||||
You can use both external file drops and internal HTML drag-and-drop in the same application. When `EnableFileDrop` is `true`, Wails intercepts external file drags but lets internal HTML5 drags pass through normally.
|
||||
|
||||
To distinguish between them in your HTML drop zone handlers, check if the drag contains files:
|
||||
|
||||
```javascript
|
||||
zone.addEventListener('dragenter', (e) => {
|
||||
// Skip external file drags - Wails handles these
|
||||
if (e.dataTransfer?.types.includes('Files')) {
|
||||
return;
|
||||
}
|
||||
// Handle internal HTML5 drags
|
||||
zone.classList.add('drag-over');
|
||||
});
|
||||
|
||||
zone.addEventListener('drop', (e) => {
|
||||
// Skip external file drops - Wails handles these
|
||||
if (e.dataTransfer?.types.includes('Files')) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
zone.classList.remove('drag-over');
|
||||
// Handle internal drop
|
||||
});
|
||||
```
|
||||
|
||||
This ensures your HTML drop handlers only respond to internal drags (like moving list items), while Wails handles external file drops separately via the `WindowFilesDropped` event.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [HTML Drag & Drop](./html) - Drag elements within your app
|
||||
- [Window Options](/features/windows/options) - All window configuration options
|
||||
232
docs/src/content/docs/features/drag-and-drop/html.mdx
Normal file
232
docs/src/content/docs/features/drag-and-drop/html.mdx
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
---
|
||||
title: HTML Drag & Drop
|
||||
description: Drag and drop elements within your application
|
||||
sidebar:
|
||||
order: 2
|
||||
---
|
||||
|
||||
HTML5 drag-and-drop lets users drag elements within your app's UI - for example, reordering a list or moving items between columns. This is standard web functionality that works in Wails without any special setup.
|
||||
|
||||
## Make an Element Draggable
|
||||
|
||||
By default, most elements can't be dragged. To make an element draggable, add `draggable="true"`:
|
||||
|
||||
```html
|
||||
<div class="item" draggable="true">Drag me</div>
|
||||
```
|
||||
|
||||
The element will now show a drag preview when the user clicks and drags it.
|
||||
|
||||
## Define a Drop Zone
|
||||
|
||||
Elements don't accept drops by default. To make an element accept drops, you need to cancel the default behaviour on `dragover`:
|
||||
|
||||
```html
|
||||
<div class="drop-zone" id="target">Drop here</div>
|
||||
|
||||
<script>
|
||||
const target = document.getElementById('target');
|
||||
|
||||
target.addEventListener('dragover', (e) => {
|
||||
e.preventDefault(); // Allow the drop
|
||||
});
|
||||
|
||||
target.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
// Handle the drop
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
Calling `preventDefault()` on `dragover` is required - it signals that this element accepts drops. Without it, the drop event won't fire.
|
||||
|
||||
## Style Drag Hover
|
||||
|
||||
To show users where they can drop, add visual feedback when dragging over a drop zone. The `dragenter` event fires when something enters the zone, and `dragleave` fires when it leaves:
|
||||
|
||||
```css
|
||||
.drop-zone {
|
||||
border: 2px dashed #ccc;
|
||||
padding: 40px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.drop-zone.drag-over {
|
||||
border-color: #007bff;
|
||||
background-color: rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
const target = document.getElementById('target');
|
||||
|
||||
target.addEventListener('dragenter', () => {
|
||||
target.classList.add('drag-over');
|
||||
});
|
||||
|
||||
target.addEventListener('dragleave', () => {
|
||||
target.classList.remove('drag-over');
|
||||
});
|
||||
|
||||
target.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
target.classList.remove('drag-over');
|
||||
// Handle the drop
|
||||
});
|
||||
```
|
||||
|
||||
Note: `dragleave` also fires when entering a child element, which can cause flickering. The complete example below shows how to handle this.
|
||||
|
||||
## Complete Example
|
||||
|
||||
A task list where items can be dragged between priority columns. This tracks the dragged element in a variable, which is the simplest approach when everything is on the same page:
|
||||
|
||||
```html
|
||||
<div class="tasks">
|
||||
<div class="item" draggable="true">Fix login bug</div>
|
||||
<div class="item" draggable="true">Update docs</div>
|
||||
<div class="item" draggable="true">Add dark mode</div>
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="drop-zone" data-priority="high">
|
||||
<h3>High Priority</h3>
|
||||
<ul></ul>
|
||||
</div>
|
||||
<div class="drop-zone" data-priority="low">
|
||||
<h3>Low Priority</h3>
|
||||
<ul></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let draggedItem = null;
|
||||
|
||||
// Track which item is being dragged
|
||||
document.querySelectorAll('.item').forEach(item => {
|
||||
item.addEventListener('dragstart', () => {
|
||||
draggedItem = item;
|
||||
item.classList.add('dragging');
|
||||
});
|
||||
|
||||
item.addEventListener('dragend', () => {
|
||||
item.classList.remove('dragging');
|
||||
});
|
||||
});
|
||||
|
||||
// Handle drops on each zone
|
||||
document.querySelectorAll('.drop-zone').forEach(zone => {
|
||||
zone.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
zone.addEventListener('dragenter', () => {
|
||||
zone.classList.add('drag-over');
|
||||
});
|
||||
|
||||
zone.addEventListener('dragleave', (e) => {
|
||||
// Only remove the class if we're leaving the zone entirely,
|
||||
// not just entering a child element
|
||||
if (!zone.contains(e.relatedTarget)) {
|
||||
zone.classList.remove('drag-over');
|
||||
}
|
||||
});
|
||||
|
||||
zone.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
zone.classList.remove('drag-over');
|
||||
|
||||
if (draggedItem) {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = draggedItem.textContent;
|
||||
zone.querySelector('ul').appendChild(li);
|
||||
draggedItem.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.item {
|
||||
padding: 12px 16px;
|
||||
background: #f0f0f0;
|
||||
margin: 8px 0;
|
||||
border-radius: 8px;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.item.dragging {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.drop-zone {
|
||||
min-height: 150px;
|
||||
border: 2px dashed #ccc;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.drop-zone.drag-over {
|
||||
border-color: #007bff;
|
||||
background: rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Combining with File Drop
|
||||
|
||||
If your app uses both HTML drag-and-drop and [File Drop](./files), your HTML drop zones will also receive events when users drag files from the operating system. To prevent confusion, filter out file drags in your handlers:
|
||||
|
||||
```javascript
|
||||
zone.addEventListener('dragenter', (e) => {
|
||||
// Ignore external file drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
|
||||
zone.classList.add('drag-over');
|
||||
});
|
||||
|
||||
zone.addEventListener('dragover', (e) => {
|
||||
// Ignore external file drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
zone.addEventListener('drop', (e) => {
|
||||
// Ignore external file drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
|
||||
e.preventDefault();
|
||||
zone.classList.remove('drag-over');
|
||||
// Handle the internal drop
|
||||
});
|
||||
```
|
||||
|
||||
The `dataTransfer.types` array contains `'Files'` when the user is dragging files from the OS, but contains types like `'text/plain'` for internal HTML drags. This lets you distinguish between the two.
|
||||
|
||||
## Passing Data with dataTransfer
|
||||
|
||||
The example above tracks the dragged element in a JavaScript variable. This works well when everything is on the same page. But if you need to drag between iframes or pass data that isn't tied to a DOM element, use the `dataTransfer` API:
|
||||
|
||||
```javascript
|
||||
// When drag starts, store data
|
||||
item.addEventListener('dragstart', (e) => {
|
||||
e.dataTransfer.setData('text/plain', item.id);
|
||||
});
|
||||
|
||||
// When dropped, retrieve the data
|
||||
target.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
const itemId = e.dataTransfer.getData('text/plain');
|
||||
const item = document.getElementById(itemId);
|
||||
// Move or copy the item
|
||||
});
|
||||
```
|
||||
|
||||
The data is stored as strings, so you'll need to serialize objects with `JSON.stringify()` if needed.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [File Drop](./files) - Accept files from the operating system
|
||||
- [MDN Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) - Full browser API reference
|
||||
|
|
@ -546,6 +546,61 @@ Assets: application.AssetOptions{
|
|||
|
||||
**See [Build System](/concepts/build-system) for details.**
|
||||
|
||||
## Input Options
|
||||
|
||||
### EnableFileDrop
|
||||
|
||||
**Type:** `bool`
|
||||
**Default:** `false`
|
||||
**Platform:** All
|
||||
|
||||
```go
|
||||
EnableFileDrop: true,
|
||||
```
|
||||
|
||||
**Purpose:** Enable drag-and-drop of files from the operating system into the window.
|
||||
|
||||
When enabled:
|
||||
- Files dragged from file managers can be dropped into your application
|
||||
- The `WindowFilesDropped` event fires with the dropped file paths
|
||||
- Elements with `data-file-drop-target` attribute provide detailed drop information
|
||||
|
||||
**Use cases:**
|
||||
- File upload interfaces
|
||||
- Document editors
|
||||
- Media importers
|
||||
- Any app that accepts files
|
||||
|
||||
**Example:**
|
||||
|
||||
```go
|
||||
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "File Uploader",
|
||||
EnableFileDrop: true,
|
||||
})
|
||||
|
||||
// Handle dropped files
|
||||
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
details := event.Context().DropTargetDetails()
|
||||
|
||||
for _, file := range files {
|
||||
fmt.Println("Dropped:", file)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**HTML drop zones:**
|
||||
|
||||
```html
|
||||
<!-- Mark elements as drop targets -->
|
||||
<div id="upload" data-file-drop-target>
|
||||
Drop files here
|
||||
</div>
|
||||
```
|
||||
|
||||
**See [File Drop](/features/drag-and-drop/files) for complete documentation.**
|
||||
|
||||
## Security Options
|
||||
|
||||
### ContentProtectionEnabled
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Wails provides native desktop capabilities:
|
|||
- [Events](/features/events/system) - Communication between components
|
||||
- [Bindings](/features/bindings/methods) - Type-safe Go ↔ JavaScript calls
|
||||
- [Clipboard](/features/clipboard) - Copy/paste operations
|
||||
- [Drag & Drop](/features/drag-drop) - File drag and drop
|
||||
- [Drag & Drop](/features/drag-and-drop/files) - File drag and drop
|
||||
- [Keyboard](/features/keyboard) - Global shortcuts
|
||||
|
||||
## Get Help
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ tasks:
|
|||
gin-routing
|
||||
gin-service
|
||||
hide-window
|
||||
html-dnd-api
|
||||
ignore-mouse
|
||||
keybindings
|
||||
liquid-glass
|
||||
|
|
@ -306,7 +305,6 @@ tasks:
|
|||
gin-routing
|
||||
gin-service
|
||||
hide-window
|
||||
html-dnd-api
|
||||
ignore-mouse
|
||||
keybindings
|
||||
liquid-glass
|
||||
|
|
|
|||
|
|
@ -20,15 +20,28 @@ After processing, the content will be moved to the main changelog and this file
|
|||
|
||||
## Changed
|
||||
<!-- Changes in existing functionality -->
|
||||
- **BREAKING:** Rename `EnableDragAndDrop` to `EnableFileDrop` in window options
|
||||
- **BREAKING:** Rename `DropZoneDetails` to `DropTargetDetails` in event context
|
||||
- **BREAKING:** Rename `DropZoneDetails()` method to `DropTargetDetails()` on `WindowEventContext`
|
||||
- **BREAKING:** Remove `WindowDropZoneFilesDropped` event, use `WindowFilesDropped` instead
|
||||
- **BREAKING:** Change HTML attribute from `data-wails-dropzone` to `data-file-drop-target`
|
||||
- **BREAKING:** Change CSS hover class from `wails-dropzone-hover` to `file-drop-target-active`
|
||||
- **BREAKING:** Remove `DragEffect`, `OnEnterEffect`, `OnOverEffect` options from Windows (were part of removed IDropTarget)
|
||||
|
||||
## Fixed
|
||||
<!-- Bug fixes -->
|
||||
- Fix file drag-and-drop on Windows not working at non-100% display scaling
|
||||
- Fix HTML5 internal drag-and-drop being broken when file drop was enabled on Windows
|
||||
- Fix file drop coordinates being in wrong pixel space on Windows (physical vs CSS pixels)
|
||||
- Fix file drag-and-drop on Linux not working reliably with hover effects
|
||||
- Fix HTML5 internal drag-and-drop being broken when file drop was enabled on Linux
|
||||
|
||||
## Deprecated
|
||||
<!-- Soon-to-be removed features -->
|
||||
|
||||
## Removed
|
||||
<!-- Features removed in this release -->
|
||||
- Remove native `IDropTarget` implementation on Windows in favor of JavaScript-based approach (matches v2 behavior)
|
||||
|
||||
## Security
|
||||
<!-- Security-related changes -->
|
||||
|
|
|
|||
|
|
@ -1,27 +1,73 @@
|
|||
# Drag-n-drop Example
|
||||
# File Drop Example
|
||||
|
||||
This example demonstrates how to handle files being dragged into the application.
|
||||
This example demonstrates how to handle files being dragged from the operating system (Finder, Explorer, file managers) into a Wails application.
|
||||
|
||||
Dropped files are automatically categorised by type and displayed in separate buckets: documents, images, or other files.
|
||||
|
||||
## How it works
|
||||
|
||||
1. Enable file drops in window options:
|
||||
```go
|
||||
EnableFileDrop: true
|
||||
```
|
||||
|
||||
2. Mark elements as drop targets in HTML:
|
||||
```html
|
||||
<div data-file-drop-target>Drop files here</div>
|
||||
```
|
||||
|
||||
3. Listen for the `WindowFilesDropped` event:
|
||||
```go
|
||||
win.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
details := event.Context().DropTargetDetails()
|
||||
// Handle the dropped files
|
||||
})
|
||||
```
|
||||
|
||||
4. Optionally forward to frontend:
|
||||
```go
|
||||
application.Get().Event.Emit("files-dropped", map[string]any{
|
||||
"files": files,
|
||||
"details": details,
|
||||
})
|
||||
```
|
||||
|
||||
## Drop Target Details
|
||||
|
||||
When files are dropped, you can get information about the drop location:
|
||||
|
||||
- `ElementID` - The ID of the element that received the drop
|
||||
- `ClassList` - CSS classes on the drop target
|
||||
- `X`, `Y` - Coordinates of the drop within the element
|
||||
|
||||
## Styling
|
||||
|
||||
When files are dragged over a valid drop target, Wails adds the `file-drop-target-active` class:
|
||||
|
||||
```css
|
||||
.file-drop-target-active {
|
||||
border-color: #4a9eff;
|
||||
background: rgba(74, 158, 255, 0.1);
|
||||
}
|
||||
```
|
||||
|
||||
## Running the example
|
||||
|
||||
To run the example, simply run the following command:
|
||||
|
||||
```bash
|
||||
go run main.go
|
||||
```
|
||||
|
||||
## Building the example
|
||||
Then drag files from your desktop or file manager into the drop zone.
|
||||
|
||||
To build the example in debug mode, simply run the following command:
|
||||
## See also
|
||||
|
||||
```bash
|
||||
wails3 task build
|
||||
```
|
||||
- [html-dnd-api](../html-dnd-api) - For dragging elements *within* your application (HTML5 Drag and Drop API)
|
||||
|
||||
# Status
|
||||
## Status
|
||||
|
||||
| Platform | Status |
|
||||
|----------|-------------|
|
||||
| Mac | Working |
|
||||
| Windows | Not Working |
|
||||
| Linux | |
|
||||
| Platform | Status |
|
||||
|----------|---------|
|
||||
| Mac | Working |
|
||||
| Windows | Working |
|
||||
| Linux | Working |
|
||||
|
|
|
|||
|
|
@ -3,422 +3,433 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>File Tree Drag-and-Drop Example</title>
|
||||
<!-- Material Icons -->
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!-- Material UI lite CSS -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
|
||||
<script defer src="https://code.getmdl.io/1.3.0/material.min.js" integrity="sha384-7/3UJ+C4EZRMEh+yDUhEZJ5YH9Ul3XW1U6AlTjHlyMowgIkG7svPJf0BN3b2CEm1" crossorigin="anonymous"></script>
|
||||
<title>Drag and Drop Demo</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background-color: #1e1e1e;
|
||||
color: #f0f0f0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #1a1a2e;
|
||||
color: #eee;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
height: calc(100vh - 140px);
|
||||
gap: 20px;
|
||||
h1 {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.file-tree {
|
||||
flex: 1;
|
||||
background-color: #2a2a2a;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.info-panel {
|
||||
flex: 1;
|
||||
background-color: #2a2a2a;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.tree-node {
|
||||
padding: 4px;
|
||||
margin: 2px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tree-node:hover {
|
||||
background-color: #3a3a3a;
|
||||
}
|
||||
|
||||
.folder {
|
||||
color: #ffca28; /* Amber for folders */
|
||||
}
|
||||
|
||||
.file {
|
||||
color: #81c784; /* Light green for files */
|
||||
}
|
||||
|
||||
.node-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.tree-children {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.dropzone {
|
||||
transition: background-color 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
/* Wails applied class for active dropzones during drag */
|
||||
.wails-dropzone-hover {
|
||||
background-color: rgba(63, 81, 181, 0.2) !important;
|
||||
box-shadow: 0 0 8px rgba(63, 81, 181, 0.5) !important;
|
||||
}
|
||||
|
||||
/* Custom styles for folder highlight */
|
||||
.folder-dropzone {
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.folder-dropzone.wails-dropzone-hover {
|
||||
border: 1px dashed #7986cb;
|
||||
box-shadow: inset 0 0 5px rgba(121, 134, 203, 0.5) !important;
|
||||
}
|
||||
|
||||
#drop-output {
|
||||
background-color: #3a3a3a;
|
||||
color: #f0f0f0;
|
||||
font-family: monospace;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
flex-grow: 1;
|
||||
white-space: pre-wrap;
|
||||
overflow: auto;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
h2 {
|
||||
color: #888;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin: 40px 0 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info-header {
|
||||
margin-bottom: 16px;
|
||||
color: #7986cb;
|
||||
.instructions {
|
||||
max-width: 900px;
|
||||
margin: 0 auto 20px;
|
||||
text-align: center;
|
||||
color: #888;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Path breadcrumb */
|
||||
.path-display {
|
||||
background-color: #3a3a3a;
|
||||
padding: 8px 16px;
|
||||
.instructions code {
|
||||
background: #16213e;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
color: #4a9eff;
|
||||
}
|
||||
|
||||
/* ===== External File Drop Section ===== */
|
||||
.external-section {
|
||||
max-width: 900px;
|
||||
margin: 0 auto 40px;
|
||||
}
|
||||
.drop-zone {
|
||||
padding: 40px;
|
||||
border: 3px dashed #444;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.drop-zone p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
}
|
||||
/* Wails adds this class when dragging files over */
|
||||
.file-drop-target-active {
|
||||
border-color: #4a9eff !important;
|
||||
background: rgba(74, 158, 255, 0.1) !important;
|
||||
box-shadow: 0 0 30px rgba(74, 158, 255, 0.2);
|
||||
}
|
||||
.file-drop-target-active p {
|
||||
color: #4a9eff;
|
||||
}
|
||||
.buckets {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.bucket {
|
||||
flex: 1;
|
||||
min-height: 150px;
|
||||
background: #16213e;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
}
|
||||
.bucket h3 {
|
||||
margin: 0 0 15px 0;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #2a3a5e;
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.bucket.documents h3 { color: #4a9eff; }
|
||||
.bucket.images h3 { color: #9b59b6; }
|
||||
.bucket.other h3 { color: #27ae60; }
|
||||
.bucket ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.bucket li {
|
||||
padding: 6px 0;
|
||||
font-family: monospace;
|
||||
color: #bbdefb;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
color: #aaa;
|
||||
word-break: break-all;
|
||||
}
|
||||
.bucket .empty {
|
||||
color: #444;
|
||||
font-style: italic;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* ===== Internal Drag Section ===== */
|
||||
.internal-section {
|
||||
max-width: 900px;
|
||||
margin: 0 auto 40px;
|
||||
}
|
||||
.internal-container {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.draggable-items {
|
||||
flex: 1;
|
||||
background: #16213e;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.draggable-items h3 {
|
||||
margin: 0 0 15px 0;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #2a3a5e;
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
color: #e67e22;
|
||||
}
|
||||
.draggable-item {
|
||||
background: #2a3a5e;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 8px;
|
||||
cursor: grab;
|
||||
transition: all 0.2s ease;
|
||||
user-select: none;
|
||||
}
|
||||
.draggable-item:hover {
|
||||
background: #3a4a6e;
|
||||
}
|
||||
.draggable-item.dragging {
|
||||
opacity: 0.5;
|
||||
cursor: grabbing;
|
||||
}
|
||||
.drop-targets {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
}
|
||||
.internal-drop-zone {
|
||||
flex: 1;
|
||||
min-height: 200px;
|
||||
background: #16213e;
|
||||
border: 2px dashed #333;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.internal-drop-zone h3 {
|
||||
margin: 0 0 15px 0;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #2a3a5e;
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.internal-drop-zone.priority-high h3 { color: #e74c3c; }
|
||||
.internal-drop-zone.priority-medium h3 { color: #f39c12; }
|
||||
.internal-drop-zone.priority-low h3 { color: #27ae60; }
|
||||
.internal-drop-zone.drag-over {
|
||||
border-color: #4a9eff;
|
||||
background: rgba(74, 158, 255, 0.1);
|
||||
}
|
||||
.internal-drop-zone ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.internal-drop-zone li {
|
||||
background: #2a3a5e;
|
||||
padding: 10px 14px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.internal-drop-zone .empty {
|
||||
color: #444;
|
||||
font-style: italic;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== Info Section ===== */
|
||||
.drop-info {
|
||||
max-width: 900px;
|
||||
margin: 20px auto 0;
|
||||
padding: 15px;
|
||||
background: #16213e;
|
||||
border-radius: 8px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
.drop-info strong {
|
||||
color: #888;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>File Tree Drag & Drop Example</h1>
|
||||
<p>Drag files onto folders to upload them to that location</p>
|
||||
<h1>Drag and Drop Demo</h1>
|
||||
|
||||
<!-- ===== External File Drop ===== -->
|
||||
<h2>External File Drop</h2>
|
||||
<div class="instructions">
|
||||
<p>
|
||||
Drop files from your operating system (Finder, Explorer, file managers).
|
||||
Uses <code>EnableFileDrop: true</code> and <code>data-file-drop-target</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="file-tree">
|
||||
<div class="path-display" id="current-path">/home/user</div>
|
||||
|
||||
<!-- Root folder -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user" data-wails-dropzone data-folder-id="root" data-folder-name="Home">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Home</span>
|
||||
<div class="external-section">
|
||||
<div class="drop-zone" data-file-drop-target>
|
||||
<p>Drop files from your desktop or file manager here</p>
|
||||
</div>
|
||||
|
||||
<div class="buckets">
|
||||
<div class="bucket documents">
|
||||
<h3>Documents</h3>
|
||||
<ul id="documents-list">
|
||||
<li class="empty">No documents yet</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<!-- Documents folder -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user/Documents" data-wails-dropzone data-folder-id="docs" data-folder-name="Documents">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Documents</span>
|
||||
<div class="bucket images">
|
||||
<h3>Images</h3>
|
||||
<ul id="images-list">
|
||||
<li class="empty">No images yet</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="bucket other">
|
||||
<h3>Other Files</h3>
|
||||
<ul id="other-list">
|
||||
<li class="empty">No other files yet</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== Internal Drag and Drop ===== -->
|
||||
<h2>Internal Drag and Drop</h2>
|
||||
<div class="instructions">
|
||||
<p>
|
||||
Drag items between zones using the HTML5 Drag and Drop API.
|
||||
Uses <code>draggable="true"</code> and standard DOM events.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="internal-section">
|
||||
<div class="internal-container">
|
||||
<div class="draggable-items">
|
||||
<h3>Tasks</h3>
|
||||
<div class="draggable-item" draggable="true" data-task="1">Fix login bug</div>
|
||||
<div class="draggable-item" draggable="true" data-task="2">Update documentation</div>
|
||||
<div class="draggable-item" draggable="true" data-task="3">Add dark mode</div>
|
||||
<div class="draggable-item" draggable="true" data-task="4">Refactor API calls</div>
|
||||
<div class="draggable-item" draggable="true" data-task="5">Write unit tests</div>
|
||||
</div>
|
||||
|
||||
<div class="drop-targets">
|
||||
<div class="internal-drop-zone priority-high" data-priority="high">
|
||||
<h3>High Priority</h3>
|
||||
<ul></ul>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<div class="tree-node file" data-path="/home/user/Documents/report.pdf">
|
||||
<span class="material-icons node-icon">description</span>
|
||||
<span>report.pdf</span>
|
||||
</div>
|
||||
<div class="tree-node file" data-path="/home/user/Documents/notes.txt">
|
||||
<span class="material-icons node-icon">description</span>
|
||||
<span>notes.txt</span>
|
||||
</div>
|
||||
<div class="internal-drop-zone priority-medium" data-priority="medium">
|
||||
<h3>Medium Priority</h3>
|
||||
<ul></ul>
|
||||
</div>
|
||||
|
||||
<!-- Pictures folder -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user/Pictures" data-wails-dropzone data-folder-id="pics" data-folder-name="Pictures">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Pictures</span>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<div class="tree-node file" data-path="/home/user/Pictures/vacation.jpg">
|
||||
<span class="material-icons node-icon">image</span>
|
||||
<span>vacation.jpg</span>
|
||||
</div>
|
||||
<div class="tree-node file" data-path="/home/user/Pictures/profile.png">
|
||||
<span class="material-icons node-icon">image</span>
|
||||
<span>profile.png</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Downloads folder -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user/Downloads" data-wails-dropzone data-folder-id="downloads" data-folder-name="Downloads">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Downloads</span>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<div class="tree-node file" data-path="/home/user/Downloads/app.dmg">
|
||||
<span class="material-icons node-icon">archive</span>
|
||||
<span>app.dmg</span>
|
||||
</div>
|
||||
<div class="tree-node file" data-path="/home/user/Downloads/data.zip">
|
||||
<span class="material-icons node-icon">archive</span>
|
||||
<span>data.zip</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Projects folder with nested structure -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user/Projects" data-wails-dropzone data-folder-id="projects" data-folder-name="Projects">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Projects</span>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<!-- Nested folder with its own dropzone -->
|
||||
<div class="tree-node folder folder-dropzone" data-path="/home/user/Projects/Wails" data-wails-dropzone data-folder-id="wails" data-folder-name="Wails">
|
||||
<span class="material-icons node-icon">folder</span>
|
||||
<span>Wails</span>
|
||||
</div>
|
||||
|
||||
<div class="tree-children">
|
||||
<div class="tree-node file" data-path="/home/user/Projects/Wails/main.go">
|
||||
<span class="material-icons node-icon">code</span>
|
||||
<span>main.go</span>
|
||||
</div>
|
||||
<div class="tree-node file" data-path="/home/user/Projects/Wails/go.mod">
|
||||
<span class="material-icons node-icon">code</span>
|
||||
<span>go.mod</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="internal-drop-zone priority-low" data-priority="low">
|
||||
<h3>Low Priority</h3>
|
||||
<ul></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-panel">
|
||||
<h2 class="info-header">Drop Information</h2>
|
||||
<div id="drop-output">Drag and drop files onto any folder in the file tree...
|
||||
</div>
|
||||
|
||||
<div class="drop-info" id="drop-info">
|
||||
<strong>Last action:</strong> <span id="drop-details">No actions yet</span>
|
||||
</div>
|
||||
|
||||
The folder elements have the following attributes:
|
||||
- data-wails-dropzone: Marks the element as a dropzone
|
||||
- data-path: Contains the full path (used for destination)
|
||||
- data-folder-id: A unique ID for the folder
|
||||
- data-folder-name: The display name of the folder</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import * as wails from "/wails/runtime.js";
|
||||
import { Events } from '/wails/runtime.js';
|
||||
|
||||
const outputDiv = document.getElementById('drop-output');
|
||||
const pathDisplay = document.getElementById('current-path');
|
||||
const folderNodes = document.querySelectorAll('.folder-dropzone');
|
||||
const documentsEl = document.getElementById('documents-list');
|
||||
const imagesEl = document.getElementById('images-list');
|
||||
const otherEl = document.getElementById('other-list');
|
||||
const dropDetails = document.getElementById('drop-details');
|
||||
|
||||
// Add debug coordinate overlay
|
||||
let debugOverlay = null;
|
||||
// ===== External File Drop =====
|
||||
const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.svg', '.webp', '.ico', '.tiff', '.tif'];
|
||||
const documentExtensions = ['.pdf', '.doc', '.docx', '.txt', '.rtf', '.odt', '.xls', '.xlsx', '.ppt', '.pptx', '.md', '.csv', '.json', '.xml', '.html', '.htm'];
|
||||
|
||||
function createDebugOverlay() {
|
||||
if (debugOverlay) return;
|
||||
|
||||
debugOverlay = document.createElement('div');
|
||||
debugOverlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
z-index: 10000;
|
||||
pointer-events: none;
|
||||
white-space: pre-line;
|
||||
`;
|
||||
document.body.appendChild(debugOverlay);
|
||||
function getFileName(path) {
|
||||
return path.split(/[/\\]/).pop();
|
||||
}
|
||||
|
||||
function updateDebugOverlay(info) {
|
||||
if (!debugOverlay) createDebugOverlay();
|
||||
debugOverlay.textContent = info;
|
||||
function getExtension(path) {
|
||||
const name = getFileName(path);
|
||||
const idx = name.lastIndexOf('.');
|
||||
return idx > 0 ? name.substring(idx).toLowerCase() : '';
|
||||
}
|
||||
|
||||
// Track mouse position and other debug info
|
||||
let mouseInfo = { x: 0, y: 0 };
|
||||
let windowInfo = { width: window.innerWidth, height: window.innerHeight };
|
||||
function categoriseFile(path) {
|
||||
const ext = getExtension(path);
|
||||
if (imageExtensions.includes(ext)) return 'images';
|
||||
if (documentExtensions.includes(ext)) return 'documents';
|
||||
return 'other';
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
mouseInfo.x = e.clientX;
|
||||
mouseInfo.y = e.clientY;
|
||||
function addFileToList(listEl, fileName) {
|
||||
const empty = listEl.querySelector('.empty');
|
||||
if (empty) empty.remove();
|
||||
|
||||
const debugInfo = `Mouse: ${e.clientX}, ${e.clientY}
|
||||
Page: ${e.pageX}, ${e.pageY}
|
||||
Screen: ${e.screenX}, ${e.screenY}
|
||||
Window: ${windowInfo.width}x${windowInfo.height}
|
||||
Viewport offset: ${window.pageXOffset}, ${window.pageYOffset}`;
|
||||
const li = document.createElement('li');
|
||||
li.textContent = fileName;
|
||||
listEl.appendChild(li);
|
||||
}
|
||||
|
||||
Events.On('files-dropped', (event) => {
|
||||
const { files, details } = event.data;
|
||||
|
||||
updateDebugOverlay(debugInfo);
|
||||
files.forEach(filePath => {
|
||||
const fileName = getFileName(filePath);
|
||||
const category = categoriseFile(filePath);
|
||||
|
||||
switch (category) {
|
||||
case 'documents':
|
||||
addFileToList(documentsEl, fileName);
|
||||
break;
|
||||
case 'images':
|
||||
addFileToList(imagesEl, fileName);
|
||||
break;
|
||||
default:
|
||||
addFileToList(otherEl, fileName);
|
||||
}
|
||||
});
|
||||
|
||||
let info = `External: ${files.length} file(s) dropped`;
|
||||
if (details) {
|
||||
info += ` at (${details.X}, ${details.Y})`;
|
||||
}
|
||||
dropDetails.textContent = info;
|
||||
});
|
||||
|
||||
// Add drag event listeners to show coordinates during drag
|
||||
document.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
const debugInfo = `[DRAGOVER]
|
||||
Mouse: ${e.clientX}, ${e.clientY}
|
||||
Page: ${e.pageX}, ${e.pageY}
|
||||
Screen: ${e.screenX}, ${e.screenY}
|
||||
Window: ${windowInfo.width}x${windowInfo.height}
|
||||
Target: ${e.target.tagName} ${e.target.className}`;
|
||||
|
||||
updateDebugOverlay(debugInfo);
|
||||
});
|
||||
// ===== Internal Drag and Drop =====
|
||||
const draggableItems = document.querySelectorAll('.draggable-item');
|
||||
const dropZones = document.querySelectorAll('.internal-drop-zone');
|
||||
|
||||
document.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
const rect = e.target.getBoundingClientRect();
|
||||
const debugInfo = `[DROP EVENT]
|
||||
Client: ${e.clientX}, ${e.clientY}
|
||||
Page: ${e.pageX}, ${e.pageY}
|
||||
Screen: ${e.screenX}, ${e.screenY}
|
||||
Target rect: ${rect.left}, ${rect.top}, ${rect.width}x${rect.height}
|
||||
Relative to target: ${e.clientX - rect.left}, ${e.clientY - rect.top}
|
||||
Window: ${windowInfo.width}x${windowInfo.height}`;
|
||||
let draggedItem = null;
|
||||
|
||||
draggableItems.forEach(item => {
|
||||
item.addEventListener('dragstart', (e) => {
|
||||
draggedItem = item;
|
||||
item.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
e.dataTransfer.setData('text/plain', item.dataset.task);
|
||||
});
|
||||
|
||||
updateDebugOverlay(debugInfo);
|
||||
console.log('Drop event debug info:', {
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY,
|
||||
pageX: e.pageX,
|
||||
pageY: e.pageY,
|
||||
screenX: e.screenX,
|
||||
screenY: e.screenY,
|
||||
targetRect: rect,
|
||||
relativeX: e.clientX - rect.left,
|
||||
relativeY: e.clientY - rect.top
|
||||
item.addEventListener('dragend', () => {
|
||||
item.classList.remove('dragging');
|
||||
draggedItem = null;
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
windowInfo.width = window.innerWidth;
|
||||
windowInfo.height = window.innerHeight;
|
||||
});
|
||||
|
||||
// Update path display when clicking folders
|
||||
folderNodes.forEach(folder => {
|
||||
folder.addEventListener('click', (e) => {
|
||||
e.stopPropagation(); // Prevent event bubbling
|
||||
const path = folder.getAttribute('data-path');
|
||||
if (path) {
|
||||
pathDisplay.textContent = path;
|
||||
outputDiv.textContent = `Selected folder: ${path}\nReady to receive files...`;
|
||||
dropZones.forEach(zone => {
|
||||
zone.addEventListener('dragenter', (e) => {
|
||||
// Ignore external file drags - only respond to internal HTML drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
e.preventDefault();
|
||||
zone.classList.add('drag-over');
|
||||
});
|
||||
|
||||
zone.addEventListener('dragover', (e) => {
|
||||
// Ignore external file drags - only respond to internal HTML drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
});
|
||||
|
||||
zone.addEventListener('dragleave', (e) => {
|
||||
// Ignore external file drags - only respond to internal HTML drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
// Only remove if leaving the zone entirely
|
||||
if (!zone.contains(e.relatedTarget)) {
|
||||
zone.classList.remove('drag-over');
|
||||
}
|
||||
});
|
||||
|
||||
zone.addEventListener('drop', (e) => {
|
||||
// Ignore external file drags - only respond to internal HTML drags
|
||||
if (e.dataTransfer?.types.includes('Files')) return;
|
||||
e.preventDefault();
|
||||
zone.classList.remove('drag-over');
|
||||
|
||||
if (draggedItem) {
|
||||
const taskText = draggedItem.textContent;
|
||||
const priority = zone.dataset.priority;
|
||||
|
||||
// Add to drop zone
|
||||
const li = document.createElement('li');
|
||||
li.textContent = taskText;
|
||||
zone.querySelector('ul').appendChild(li);
|
||||
|
||||
// Remove from source
|
||||
draggedItem.remove();
|
||||
|
||||
dropDetails.textContent = `Internal: "${taskText}" moved to ${priority} priority`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Listen for the file drop event from Wails
|
||||
wails.Events.On("frontend:FileDropInfo", (eventData) => {
|
||||
console.log("=============== Frontend: File Drop Debug Info ===============");
|
||||
console.log("Full event data:", eventData);
|
||||
|
||||
const { files, targetID, targetClasses, dropX, dropY, attributes } = eventData.data[0];
|
||||
|
||||
console.log("Extracted data:", {
|
||||
files,
|
||||
targetID,
|
||||
targetClasses,
|
||||
dropX,
|
||||
dropY,
|
||||
attributes
|
||||
});
|
||||
|
||||
// Get additional folder information from the attributes
|
||||
const folderPath = attributes ? attributes['data-path'] : 'Unknown path';
|
||||
const folderName = attributes ? attributes['data-folder-name'] : 'Unknown folder';
|
||||
|
||||
let message = `=============== FILE DROP DEBUG REPORT ===============\n`;
|
||||
message += `Files dropped on folder: ${folderName}\n`;
|
||||
message += `Target path: ${folderPath}\n`;
|
||||
message += `Element ID: ${targetID || 'N/A'}\n`;
|
||||
message += `Element Classes: ${targetClasses && targetClasses.length > 0 ? targetClasses.join(', ') : 'N/A'}\n`;
|
||||
message += `\n=== COORDINATE DEBUG INFO ===\n`;
|
||||
message += `Drop Coordinates from Wails: X=${dropX.toFixed(2)}, Y=${dropY.toFixed(2)}\n`;
|
||||
message += `Current Mouse Position: X=${mouseInfo.x}, Y=${mouseInfo.y}\n`;
|
||||
message += `Window Size: ${windowInfo.width}x${windowInfo.height}\n`;
|
||||
|
||||
// Get the target element to show its position
|
||||
const targetElement = document.querySelector(`[data-folder-id="${targetID}"]`);
|
||||
if (targetElement) {
|
||||
const rect = targetElement.getBoundingClientRect();
|
||||
message += `Target Element Position:\n`;
|
||||
message += ` - Bounding rect: left=${rect.left}, top=${rect.top}, right=${rect.right}, bottom=${rect.bottom}\n`;
|
||||
message += ` - Size: ${rect.width}x${rect.height}\n`;
|
||||
message += ` - Center: ${rect.left + rect.width/2}, ${rect.top + rect.height/2}\n`;
|
||||
message += ` - Drop relative to element: X=${dropX - rect.left}, Y=${dropY - rect.top}\n`;
|
||||
}
|
||||
|
||||
message += `\n=== ELEMENT ATTRIBUTES ===\n`;
|
||||
if (attributes && Object.keys(attributes).length > 0) {
|
||||
Object.entries(attributes).forEach(([key, value]) => {
|
||||
message += ` ${key}: "${value}"\n`;
|
||||
});
|
||||
} else {
|
||||
message += " No attributes found\n";
|
||||
}
|
||||
|
||||
message += `\n=== DROPPED FILES ===\n`;
|
||||
files.forEach((file, index) => {
|
||||
message += ` ${index + 1}. ${file}\n`;
|
||||
});
|
||||
|
||||
message += `\n=== SIMULATION ===\n`;
|
||||
message += `Simulating upload to ${folderPath}...\n`;
|
||||
message += `===========================================`;
|
||||
|
||||
outputDiv.textContent = message;
|
||||
|
||||
console.log("=============== End Frontend Debug ===============");
|
||||
});
|
||||
|
||||
console.log("File Tree Drag-and-Drop example initialized with enhanced debugging.");
|
||||
createDebugOverlay();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
|
|
@ -14,153 +11,50 @@ import (
|
|||
//go:embed assets
|
||||
var assets embed.FS
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
app *application.App
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// Startup is called when the app starts. The context is saved
|
||||
// so we can call the runtime methods
|
||||
func (a *App) Startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
a.app = application.Get()
|
||||
}
|
||||
|
||||
// FileDropInfo defines the payload for the file drop event sent to the frontend.
|
||||
type FileDropInfo struct {
|
||||
Files []string `json:"files"`
|
||||
TargetID string `json:"targetID"`
|
||||
TargetClasses []string `json:"targetClasses"`
|
||||
DropX float64 `json:"dropX"`
|
||||
DropY float64 `json:"dropY"`
|
||||
Attributes map[string]string `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// FilesDroppedOnTarget is called when files are dropped onto a registered drop target
|
||||
// or the window if no specific target is hit.
|
||||
func FilesDroppedOnTarget(
|
||||
files []string,
|
||||
targetID string,
|
||||
targetClasses []string,
|
||||
dropX float64,
|
||||
dropY float64,
|
||||
isTargetDropzone bool, // This parameter is kept for logging but not sent to frontend in this event
|
||||
attributes map[string]string,
|
||||
) {
|
||||
log.Println("=============== Go: FilesDroppedOnTarget Debug Info ===============")
|
||||
log.Println(fmt.Sprintf(" Files: %v", files))
|
||||
log.Println(fmt.Sprintf(" Target ID: '%s'", targetID))
|
||||
log.Println(fmt.Sprintf(" Target Classes: %v", targetClasses))
|
||||
log.Println(fmt.Sprintf(" Drop X: %f, Drop Y: %f", dropX, dropY))
|
||||
log.Println(
|
||||
fmt.Sprintf(
|
||||
" Drop occurred on a designated dropzone (runtime validated before this Go event): %t",
|
||||
isTargetDropzone,
|
||||
),
|
||||
)
|
||||
log.Println(fmt.Sprintf(" Element Attributes: %v", attributes))
|
||||
log.Println("================================================================")
|
||||
|
||||
payload := FileDropInfo{
|
||||
Files: files,
|
||||
TargetID: targetID,
|
||||
TargetClasses: targetClasses,
|
||||
DropX: dropX,
|
||||
DropY: dropY,
|
||||
Attributes: attributes,
|
||||
}
|
||||
|
||||
log.Println("Go: Emitted 'frontend:FileDropInfo' event with payload:", payload)
|
||||
}
|
||||
|
||||
func main() {
|
||||
appInstance := NewApp()
|
||||
|
||||
app := application.New(application.Options{
|
||||
Name: "Drag-n-drop Demo",
|
||||
Description: "A demo of the Drag-n-drop API",
|
||||
Name: "File Drop Demo",
|
||||
Description: "A demo of file drag and drop",
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.BundledAssetFileServer(assets),
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||
},
|
||||
Services: []application.Service{
|
||||
application.NewService(appInstance),
|
||||
},
|
||||
})
|
||||
|
||||
win := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Drag-n-drop Demo",
|
||||
Title: "File Drop Demo",
|
||||
Width: 800,
|
||||
Height: 600,
|
||||
EnableFileDrop: true,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInsetUnified,
|
||||
InvisibleTitleBarHeight: 50,
|
||||
},
|
||||
EnableDragAndDrop: true,
|
||||
})
|
||||
|
||||
log.Println("Setting up event listener for 'WindowDropZoneFilesDropped'...")
|
||||
win.OnWindowEvent(
|
||||
events.Common.WindowDropZoneFilesDropped,
|
||||
func(event *application.WindowEvent) {
|
||||
// Listen for file drop events
|
||||
win.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
|
||||
files := event.Context().DroppedFiles()
|
||||
details := event.Context().DropTargetDetails()
|
||||
|
||||
droppedFiles := event.Context().DroppedFiles()
|
||||
details := event.Context().DropZoneDetails()
|
||||
log.Printf("Files dropped: %v", files)
|
||||
if details != nil {
|
||||
log.Printf("Drop target: id=%s, classes=%v, x=%d, y=%d",
|
||||
details.ElementID, details.ClassList, details.X, details.Y)
|
||||
}
|
||||
|
||||
log.Printf("Dropped files count: %d", len(droppedFiles))
|
||||
log.Printf("Event context: %+v", event.Context())
|
||||
|
||||
if details != nil {
|
||||
log.Printf("DropZone details found:")
|
||||
log.Printf(" ElementID: '%s'", details.ElementID)
|
||||
log.Printf(" ClassList: %v", details.ClassList)
|
||||
log.Printf(" X: %d, Y: %d", details.X, details.Y)
|
||||
log.Printf(" Attributes: %+v", details.Attributes)
|
||||
|
||||
// Call the App method with the extracted data
|
||||
FilesDroppedOnTarget(
|
||||
droppedFiles,
|
||||
details.ElementID,
|
||||
details.ClassList,
|
||||
float64(details.X),
|
||||
float64(details.Y),
|
||||
details.ElementID != "", // isTargetDropzone based on whether an ID was found
|
||||
details.Attributes,
|
||||
)
|
||||
} else {
|
||||
log.Println("DropZone details are nil - drop was not on a specific registered zone")
|
||||
// This case might occur if DropZoneDetails are nil, meaning the drop was not on a specific registered zone
|
||||
// or if the context itself was problematic.
|
||||
FilesDroppedOnTarget(droppedFiles, "", nil, 0, 0, false, nil)
|
||||
}
|
||||
|
||||
payload := FileDropInfo{
|
||||
Files: droppedFiles,
|
||||
TargetID: details.ElementID,
|
||||
TargetClasses: details.ClassList,
|
||||
DropX: float64(details.X),
|
||||
DropY: float64(details.Y),
|
||||
Attributes: details.Attributes, // Add the attributes
|
||||
}
|
||||
|
||||
log.Printf("Emitting event payload: %+v", payload)
|
||||
application.Get().Event.Emit("frontend:FileDropInfo", payload)
|
||||
log.Println(
|
||||
"=============== End WindowDropZoneFilesDropped Event Debug ===============",
|
||||
)
|
||||
},
|
||||
)
|
||||
// Emit event to frontend
|
||||
application.Get().Event.Emit("files-dropped", map[string]any{
|
||||
"files": files,
|
||||
"details": details,
|
||||
})
|
||||
})
|
||||
|
||||
err := app.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
# HTML Drag and Drop API Example
|
||||
|
||||
This example should demonstrate whether the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API") works correctly.
|
||||
|
||||
## Expected Behaviour
|
||||
|
||||
When dragging the "draggable", in the console should be printed:
|
||||
1. "dragstart" once
|
||||
2. "drag" many times
|
||||
3. "dragend" once
|
||||
|
||||
When dragging the "draggable" on the drop target, the inner text of the latter shoud change and in the console should be printed:
|
||||
1. "dragstart" once
|
||||
2. "drag" many times
|
||||
3. "dragenter" once
|
||||
4. "dragover" many times (alternating with "drag")
|
||||
5. - "drop" once (in case of a drop inside the drop target)
|
||||
- "dragleave" once (in case the draggable div leaves the drop target)
|
||||
6. "dragend" once
|
||||
|
||||
## Running the example
|
||||
|
||||
To run the example, simply run the following command:
|
||||
|
||||
```bash
|
||||
go run main.go
|
||||
```
|
||||
|
||||
## Building the example
|
||||
|
||||
To build the example in debug mode, simply run the following command:
|
||||
|
||||
```bash
|
||||
wails3 task build
|
||||
```
|
||||
|
||||
# Status
|
||||
|
||||
| Platform | Status |
|
||||
|----------|-------------|
|
||||
| Mac | Working |
|
||||
| Windows | Not Working |
|
||||
| Linux | |
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<style>
|
||||
body{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#draggable {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: yellow;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#dropTarget {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 2px solid red;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>HTML Drag and Drop API Demo</h1>
|
||||
<br/>
|
||||
|
||||
<div id="draggable" draggable="true" >draggable</div>
|
||||
|
||||
<div id="dropTarget" >drop target</div>
|
||||
|
||||
</body>
|
||||
|
||||
<script type="module">
|
||||
const draggable = document.getElementById('draggable');
|
||||
|
||||
draggable.addEventListener('dragstart', (event) => {
|
||||
console.log('dragstart');
|
||||
dropTarget.innerText = 'drop target';
|
||||
});
|
||||
|
||||
draggable.addEventListener("drag", (event) => {
|
||||
console.log('drag');
|
||||
});
|
||||
|
||||
draggable.addEventListener("dragend", (event) => {
|
||||
console.log('dragend');
|
||||
});
|
||||
|
||||
const dropTarget = document.getElementById('dropTarget');
|
||||
|
||||
dropTarget.addEventListener('dragenter', (event) => {
|
||||
console.log('dragenter');
|
||||
});
|
||||
|
||||
dropTarget.addEventListener('dragleave', (event) => {
|
||||
console.log('dragleave');
|
||||
dropTarget.innerText = 'left drop target';
|
||||
});
|
||||
|
||||
dropTarget.addEventListener('dragover', (event) => {
|
||||
event.preventDefault()
|
||||
console.log('dragover');
|
||||
dropTarget.innerText = 'dragged over';
|
||||
});
|
||||
|
||||
dropTarget.addEventListener('drop', (event) => {
|
||||
console.log('drop');
|
||||
dropTarget.innerText = 'dropped';
|
||||
});
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
//go:embed assets
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
app := application.New(application.Options{
|
||||
Name: "HTML Drag and Drop API Demo",
|
||||
Description: "A demo of the HTML Drag and drop API",
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.BundledAssetFileServer(assets),
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||
},
|
||||
})
|
||||
|
||||
app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Drag-n-drop Demo",
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInsetUnified,
|
||||
InvisibleTitleBarHeight: 50,
|
||||
},
|
||||
})
|
||||
|
||||
err := app.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -61,15 +61,15 @@ func main() {
|
|||
|
||||
// Window 1: Light style with no tint
|
||||
window1 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Light Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 100,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: lightHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Light Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 100,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: lightHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -84,15 +84,15 @@ func main() {
|
|||
|
||||
// Window 2: Dark style
|
||||
window2 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Dark Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 500,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: darkHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Dark Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 500,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: darkHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -107,15 +107,15 @@ func main() {
|
|||
|
||||
// Window 3: Vibrant style
|
||||
window3 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Vibrant Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 900,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: vibrantHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Vibrant Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 900,
|
||||
Y: 100,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: vibrantHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -130,15 +130,15 @@ func main() {
|
|||
|
||||
// Window 4: Blue tinted glass
|
||||
window4 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Tinted Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 300,
|
||||
Y: 420,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: tintedHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Tinted Glass",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 300,
|
||||
Y: 420,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: tintedHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -153,15 +153,15 @@ func main() {
|
|||
|
||||
// Window 5: Using specific NSVisualEffectMaterial
|
||||
window5 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Sheet Material",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 700,
|
||||
Y: 420,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: sheetHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Sheet Material",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 700,
|
||||
Y: 420,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: sheetHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -176,15 +176,15 @@ func main() {
|
|||
|
||||
// Window 6: HUD Window Material (very light, translucent)
|
||||
window6 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "HUD Window",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 100,
|
||||
Y: 740,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: hudHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "HUD Window",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 100,
|
||||
Y: 740,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: hudHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
@ -199,15 +199,15 @@ func main() {
|
|||
|
||||
// Window 7: Content Background Material
|
||||
window7 := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Content Background",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 500,
|
||||
Y: 740,
|
||||
Frameless: true,
|
||||
EnableDragAndDrop: false,
|
||||
HTML: contentHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Title: "Content Background",
|
||||
Width: 350,
|
||||
Height: 280,
|
||||
X: 500,
|
||||
Y: 740,
|
||||
Frameless: true,
|
||||
EnableFileDrop: false,
|
||||
HTML: contentHTML,
|
||||
InitialPosition: application.WindowXY,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropLiquidGlass,
|
||||
InvisibleTitleBarHeight: 500,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -6,218 +6,217 @@ func IsKnownEvent(name string) bool {
|
|||
}
|
||||
|
||||
var knownEvents = map[string]struct{}{
|
||||
"common:ApplicationOpenedWithFile": {},
|
||||
"common:ApplicationStarted": {},
|
||||
"common:ApplicationLaunchedWithUrl": {},
|
||||
"common:ThemeChanged": {},
|
||||
"common:WindowClosing": {},
|
||||
"common:WindowDidMove": {},
|
||||
"common:WindowDidResize": {},
|
||||
"common:WindowDPIChanged": {},
|
||||
"common:WindowFilesDropped": {},
|
||||
"common:WindowFocus": {},
|
||||
"common:WindowFullscreen": {},
|
||||
"common:WindowHide": {},
|
||||
"common:WindowLostFocus": {},
|
||||
"common:WindowMaximise": {},
|
||||
"common:WindowMinimise": {},
|
||||
"common:WindowToggleFrameless": {},
|
||||
"common:WindowRestore": {},
|
||||
"common:WindowRuntimeReady": {},
|
||||
"common:WindowShow": {},
|
||||
"common:WindowUnFullscreen": {},
|
||||
"common:WindowUnMaximise": {},
|
||||
"common:WindowUnMinimise": {},
|
||||
"common:WindowZoom": {},
|
||||
"common:WindowZoomIn": {},
|
||||
"common:WindowZoomOut": {},
|
||||
"common:WindowZoomReset": {},
|
||||
"common:WindowDropZoneFilesDropped": {},
|
||||
"linux:ApplicationStartup": {},
|
||||
"linux:SystemThemeChanged": {},
|
||||
"linux:WindowDeleteEvent": {},
|
||||
"linux:WindowDidMove": {},
|
||||
"linux:WindowDidResize": {},
|
||||
"linux:WindowFocusIn": {},
|
||||
"linux:WindowFocusOut": {},
|
||||
"linux:WindowLoadStarted": {},
|
||||
"linux:WindowLoadRedirected": {},
|
||||
"linux:WindowLoadCommitted": {},
|
||||
"linux:WindowLoadFinished": {},
|
||||
"mac:ApplicationDidBecomeActive": {},
|
||||
"mac:ApplicationDidChangeBackingProperties": {},
|
||||
"mac:ApplicationDidChangeEffectiveAppearance": {},
|
||||
"mac:ApplicationDidChangeIcon": {},
|
||||
"mac:ApplicationDidChangeOcclusionState": {},
|
||||
"mac:ApplicationDidChangeScreenParameters": {},
|
||||
"mac:ApplicationDidChangeStatusBarFrame": {},
|
||||
"mac:ApplicationDidChangeStatusBarOrientation": {},
|
||||
"mac:ApplicationDidChangeTheme": {},
|
||||
"mac:ApplicationDidFinishLaunching": {},
|
||||
"mac:ApplicationDidHide": {},
|
||||
"mac:ApplicationDidResignActive": {},
|
||||
"mac:ApplicationDidUnhide": {},
|
||||
"mac:ApplicationDidUpdate": {},
|
||||
"mac:ApplicationShouldHandleReopen": {},
|
||||
"mac:ApplicationWillBecomeActive": {},
|
||||
"mac:ApplicationWillFinishLaunching": {},
|
||||
"mac:ApplicationWillHide": {},
|
||||
"mac:ApplicationWillResignActive": {},
|
||||
"mac:ApplicationWillTerminate": {},
|
||||
"mac:ApplicationWillUnhide": {},
|
||||
"mac:ApplicationWillUpdate": {},
|
||||
"mac:MenuDidAddItem": {},
|
||||
"mac:MenuDidBeginTracking": {},
|
||||
"mac:MenuDidClose": {},
|
||||
"mac:MenuDidDisplayItem": {},
|
||||
"mac:MenuDidEndTracking": {},
|
||||
"mac:MenuDidHighlightItem": {},
|
||||
"mac:MenuDidOpen": {},
|
||||
"mac:MenuDidPopUp": {},
|
||||
"mac:MenuDidRemoveItem": {},
|
||||
"mac:MenuDidSendAction": {},
|
||||
"mac:MenuDidSendActionToItem": {},
|
||||
"mac:MenuDidUpdate": {},
|
||||
"mac:MenuWillAddItem": {},
|
||||
"mac:MenuWillBeginTracking": {},
|
||||
"mac:MenuWillDisplayItem": {},
|
||||
"mac:MenuWillEndTracking": {},
|
||||
"mac:MenuWillHighlightItem": {},
|
||||
"mac:MenuWillOpen": {},
|
||||
"mac:MenuWillPopUp": {},
|
||||
"mac:MenuWillRemoveItem": {},
|
||||
"mac:MenuWillSendAction": {},
|
||||
"mac:MenuWillSendActionToItem": {},
|
||||
"mac:MenuWillUpdate": {},
|
||||
"mac:WebViewDidCommitNavigation": {},
|
||||
"mac:WebViewDidFinishNavigation": {},
|
||||
"common:ApplicationOpenedWithFile": {},
|
||||
"common:ApplicationStarted": {},
|
||||
"common:ApplicationLaunchedWithUrl": {},
|
||||
"common:ThemeChanged": {},
|
||||
"common:WindowClosing": {},
|
||||
"common:WindowDidMove": {},
|
||||
"common:WindowDidResize": {},
|
||||
"common:WindowDPIChanged": {},
|
||||
"common:WindowFilesDropped": {},
|
||||
"common:WindowFocus": {},
|
||||
"common:WindowFullscreen": {},
|
||||
"common:WindowHide": {},
|
||||
"common:WindowLostFocus": {},
|
||||
"common:WindowMaximise": {},
|
||||
"common:WindowMinimise": {},
|
||||
"common:WindowToggleFrameless": {},
|
||||
"common:WindowRestore": {},
|
||||
"common:WindowRuntimeReady": {},
|
||||
"common:WindowShow": {},
|
||||
"common:WindowUnFullscreen": {},
|
||||
"common:WindowUnMaximise": {},
|
||||
"common:WindowUnMinimise": {},
|
||||
"common:WindowZoom": {},
|
||||
"common:WindowZoomIn": {},
|
||||
"common:WindowZoomOut": {},
|
||||
"common:WindowZoomReset": {},
|
||||
"linux:ApplicationStartup": {},
|
||||
"linux:SystemThemeChanged": {},
|
||||
"linux:WindowDeleteEvent": {},
|
||||
"linux:WindowDidMove": {},
|
||||
"linux:WindowDidResize": {},
|
||||
"linux:WindowFocusIn": {},
|
||||
"linux:WindowFocusOut": {},
|
||||
"linux:WindowLoadStarted": {},
|
||||
"linux:WindowLoadRedirected": {},
|
||||
"linux:WindowLoadCommitted": {},
|
||||
"linux:WindowLoadFinished": {},
|
||||
"mac:ApplicationDidBecomeActive": {},
|
||||
"mac:ApplicationDidChangeBackingProperties": {},
|
||||
"mac:ApplicationDidChangeEffectiveAppearance": {},
|
||||
"mac:ApplicationDidChangeIcon": {},
|
||||
"mac:ApplicationDidChangeOcclusionState": {},
|
||||
"mac:ApplicationDidChangeScreenParameters": {},
|
||||
"mac:ApplicationDidChangeStatusBarFrame": {},
|
||||
"mac:ApplicationDidChangeStatusBarOrientation": {},
|
||||
"mac:ApplicationDidChangeTheme": {},
|
||||
"mac:ApplicationDidFinishLaunching": {},
|
||||
"mac:ApplicationDidHide": {},
|
||||
"mac:ApplicationDidResignActive": {},
|
||||
"mac:ApplicationDidUnhide": {},
|
||||
"mac:ApplicationDidUpdate": {},
|
||||
"mac:ApplicationShouldHandleReopen": {},
|
||||
"mac:ApplicationWillBecomeActive": {},
|
||||
"mac:ApplicationWillFinishLaunching": {},
|
||||
"mac:ApplicationWillHide": {},
|
||||
"mac:ApplicationWillResignActive": {},
|
||||
"mac:ApplicationWillTerminate": {},
|
||||
"mac:ApplicationWillUnhide": {},
|
||||
"mac:ApplicationWillUpdate": {},
|
||||
"mac:MenuDidAddItem": {},
|
||||
"mac:MenuDidBeginTracking": {},
|
||||
"mac:MenuDidClose": {},
|
||||
"mac:MenuDidDisplayItem": {},
|
||||
"mac:MenuDidEndTracking": {},
|
||||
"mac:MenuDidHighlightItem": {},
|
||||
"mac:MenuDidOpen": {},
|
||||
"mac:MenuDidPopUp": {},
|
||||
"mac:MenuDidRemoveItem": {},
|
||||
"mac:MenuDidSendAction": {},
|
||||
"mac:MenuDidSendActionToItem": {},
|
||||
"mac:MenuDidUpdate": {},
|
||||
"mac:MenuWillAddItem": {},
|
||||
"mac:MenuWillBeginTracking": {},
|
||||
"mac:MenuWillDisplayItem": {},
|
||||
"mac:MenuWillEndTracking": {},
|
||||
"mac:MenuWillHighlightItem": {},
|
||||
"mac:MenuWillOpen": {},
|
||||
"mac:MenuWillPopUp": {},
|
||||
"mac:MenuWillRemoveItem": {},
|
||||
"mac:MenuWillSendAction": {},
|
||||
"mac:MenuWillSendActionToItem": {},
|
||||
"mac:MenuWillUpdate": {},
|
||||
"mac:WebViewDidCommitNavigation": {},
|
||||
"mac:WebViewDidFinishNavigation": {},
|
||||
"mac:WebViewDidReceiveServerRedirectForProvisionalNavigation": {},
|
||||
"mac:WebViewDidStartProvisionalNavigation": {},
|
||||
"mac:WindowDidBecomeKey": {},
|
||||
"mac:WindowDidBecomeMain": {},
|
||||
"mac:WindowDidBeginSheet": {},
|
||||
"mac:WindowDidChangeAlpha": {},
|
||||
"mac:WindowDidChangeBackingLocation": {},
|
||||
"mac:WindowDidChangeBackingProperties": {},
|
||||
"mac:WindowDidChangeCollectionBehavior": {},
|
||||
"mac:WindowDidChangeEffectiveAppearance": {},
|
||||
"mac:WindowDidChangeOcclusionState": {},
|
||||
"mac:WindowDidChangeOrderingMode": {},
|
||||
"mac:WindowDidChangeScreen": {},
|
||||
"mac:WindowDidChangeScreenParameters": {},
|
||||
"mac:WindowDidChangeScreenProfile": {},
|
||||
"mac:WindowDidChangeScreenSpace": {},
|
||||
"mac:WindowDidChangeScreenSpaceProperties": {},
|
||||
"mac:WindowDidChangeSharingType": {},
|
||||
"mac:WindowDidChangeSpace": {},
|
||||
"mac:WindowDidChangeSpaceOrderingMode": {},
|
||||
"mac:WindowDidChangeTitle": {},
|
||||
"mac:WindowDidChangeToolbar": {},
|
||||
"mac:WindowDidDeminiaturize": {},
|
||||
"mac:WindowDidEndSheet": {},
|
||||
"mac:WindowDidEnterFullScreen": {},
|
||||
"mac:WindowDidEnterVersionBrowser": {},
|
||||
"mac:WindowDidExitFullScreen": {},
|
||||
"mac:WindowDidExitVersionBrowser": {},
|
||||
"mac:WindowDidExpose": {},
|
||||
"mac:WindowDidFocus": {},
|
||||
"mac:WindowDidMiniaturize": {},
|
||||
"mac:WindowDidMove": {},
|
||||
"mac:WindowDidOrderOffScreen": {},
|
||||
"mac:WindowDidOrderOnScreen": {},
|
||||
"mac:WindowDidResignKey": {},
|
||||
"mac:WindowDidResignMain": {},
|
||||
"mac:WindowDidResize": {},
|
||||
"mac:WindowDidUpdate": {},
|
||||
"mac:WindowDidUpdateAlpha": {},
|
||||
"mac:WindowDidUpdateCollectionBehavior": {},
|
||||
"mac:WindowDidUpdateCollectionProperties": {},
|
||||
"mac:WindowDidUpdateShadow": {},
|
||||
"mac:WindowDidUpdateTitle": {},
|
||||
"mac:WindowDidUpdateToolbar": {},
|
||||
"mac:WindowDidZoom": {},
|
||||
"mac:WindowFileDraggingEntered": {},
|
||||
"mac:WindowFileDraggingExited": {},
|
||||
"mac:WindowFileDraggingPerformed": {},
|
||||
"mac:WindowHide": {},
|
||||
"mac:WindowMaximise": {},
|
||||
"mac:WindowUnMaximise": {},
|
||||
"mac:WindowMinimise": {},
|
||||
"mac:WindowUnMinimise": {},
|
||||
"mac:WindowShouldClose": {},
|
||||
"mac:WindowShow": {},
|
||||
"mac:WindowWillBecomeKey": {},
|
||||
"mac:WindowWillBecomeMain": {},
|
||||
"mac:WindowWillBeginSheet": {},
|
||||
"mac:WindowWillChangeOrderingMode": {},
|
||||
"mac:WindowWillClose": {},
|
||||
"mac:WindowWillDeminiaturize": {},
|
||||
"mac:WindowWillEnterFullScreen": {},
|
||||
"mac:WindowWillEnterVersionBrowser": {},
|
||||
"mac:WindowWillExitFullScreen": {},
|
||||
"mac:WindowWillExitVersionBrowser": {},
|
||||
"mac:WindowWillFocus": {},
|
||||
"mac:WindowWillMiniaturize": {},
|
||||
"mac:WindowWillMove": {},
|
||||
"mac:WindowWillOrderOffScreen": {},
|
||||
"mac:WindowWillOrderOnScreen": {},
|
||||
"mac:WindowWillResignMain": {},
|
||||
"mac:WindowWillResize": {},
|
||||
"mac:WindowWillUnfocus": {},
|
||||
"mac:WindowWillUpdate": {},
|
||||
"mac:WindowWillUpdateAlpha": {},
|
||||
"mac:WindowWillUpdateCollectionBehavior": {},
|
||||
"mac:WindowWillUpdateCollectionProperties": {},
|
||||
"mac:WindowWillUpdateShadow": {},
|
||||
"mac:WindowWillUpdateTitle": {},
|
||||
"mac:WindowWillUpdateToolbar": {},
|
||||
"mac:WindowWillUpdateVisibility": {},
|
||||
"mac:WindowWillUseStandardFrame": {},
|
||||
"mac:WindowZoomIn": {},
|
||||
"mac:WindowZoomOut": {},
|
||||
"mac:WindowZoomReset": {},
|
||||
"windows:APMPowerSettingChange": {},
|
||||
"windows:APMPowerStatusChange": {},
|
||||
"windows:APMResumeAutomatic": {},
|
||||
"windows:APMResumeSuspend": {},
|
||||
"windows:APMSuspend": {},
|
||||
"windows:ApplicationStarted": {},
|
||||
"windows:SystemThemeChanged": {},
|
||||
"windows:WebViewNavigationCompleted": {},
|
||||
"windows:WindowActive": {},
|
||||
"windows:WindowBackgroundErase": {},
|
||||
"windows:WindowClickActive": {},
|
||||
"windows:WindowClosing": {},
|
||||
"windows:WindowDidMove": {},
|
||||
"windows:WindowDidResize": {},
|
||||
"windows:WindowDPIChanged": {},
|
||||
"windows:WindowDragDrop": {},
|
||||
"windows:WindowDragEnter": {},
|
||||
"windows:WindowDragLeave": {},
|
||||
"windows:WindowDragOver": {},
|
||||
"windows:WindowEndMove": {},
|
||||
"windows:WindowEndResize": {},
|
||||
"windows:WindowFullscreen": {},
|
||||
"windows:WindowHide": {},
|
||||
"windows:WindowInactive": {},
|
||||
"windows:WindowKeyDown": {},
|
||||
"windows:WindowKeyUp": {},
|
||||
"windows:WindowKillFocus": {},
|
||||
"windows:WindowNonClientHit": {},
|
||||
"windows:WindowNonClientMouseDown": {},
|
||||
"windows:WindowNonClientMouseLeave": {},
|
||||
"windows:WindowNonClientMouseMove": {},
|
||||
"windows:WindowNonClientMouseUp": {},
|
||||
"windows:WindowPaint": {},
|
||||
"windows:WindowRestore": {},
|
||||
"windows:WindowSetFocus": {},
|
||||
"windows:WindowShow": {},
|
||||
"windows:WindowStartMove": {},
|
||||
"windows:WindowStartResize": {},
|
||||
"windows:WindowUnFullscreen": {},
|
||||
"windows:WindowZOrderChanged": {},
|
||||
"windows:WindowMinimise": {},
|
||||
"windows:WindowUnMinimise": {},
|
||||
"windows:WindowMaximise": {},
|
||||
"windows:WindowUnMaximise": {},
|
||||
"mac:WebViewDidStartProvisionalNavigation": {},
|
||||
"mac:WindowDidBecomeKey": {},
|
||||
"mac:WindowDidBecomeMain": {},
|
||||
"mac:WindowDidBeginSheet": {},
|
||||
"mac:WindowDidChangeAlpha": {},
|
||||
"mac:WindowDidChangeBackingLocation": {},
|
||||
"mac:WindowDidChangeBackingProperties": {},
|
||||
"mac:WindowDidChangeCollectionBehavior": {},
|
||||
"mac:WindowDidChangeEffectiveAppearance": {},
|
||||
"mac:WindowDidChangeOcclusionState": {},
|
||||
"mac:WindowDidChangeOrderingMode": {},
|
||||
"mac:WindowDidChangeScreen": {},
|
||||
"mac:WindowDidChangeScreenParameters": {},
|
||||
"mac:WindowDidChangeScreenProfile": {},
|
||||
"mac:WindowDidChangeScreenSpace": {},
|
||||
"mac:WindowDidChangeScreenSpaceProperties": {},
|
||||
"mac:WindowDidChangeSharingType": {},
|
||||
"mac:WindowDidChangeSpace": {},
|
||||
"mac:WindowDidChangeSpaceOrderingMode": {},
|
||||
"mac:WindowDidChangeTitle": {},
|
||||
"mac:WindowDidChangeToolbar": {},
|
||||
"mac:WindowDidDeminiaturize": {},
|
||||
"mac:WindowDidEndSheet": {},
|
||||
"mac:WindowDidEnterFullScreen": {},
|
||||
"mac:WindowDidEnterVersionBrowser": {},
|
||||
"mac:WindowDidExitFullScreen": {},
|
||||
"mac:WindowDidExitVersionBrowser": {},
|
||||
"mac:WindowDidExpose": {},
|
||||
"mac:WindowDidFocus": {},
|
||||
"mac:WindowDidMiniaturize": {},
|
||||
"mac:WindowDidMove": {},
|
||||
"mac:WindowDidOrderOffScreen": {},
|
||||
"mac:WindowDidOrderOnScreen": {},
|
||||
"mac:WindowDidResignKey": {},
|
||||
"mac:WindowDidResignMain": {},
|
||||
"mac:WindowDidResize": {},
|
||||
"mac:WindowDidUpdate": {},
|
||||
"mac:WindowDidUpdateAlpha": {},
|
||||
"mac:WindowDidUpdateCollectionBehavior": {},
|
||||
"mac:WindowDidUpdateCollectionProperties": {},
|
||||
"mac:WindowDidUpdateShadow": {},
|
||||
"mac:WindowDidUpdateTitle": {},
|
||||
"mac:WindowDidUpdateToolbar": {},
|
||||
"mac:WindowDidZoom": {},
|
||||
"mac:WindowFileDraggingEntered": {},
|
||||
"mac:WindowFileDraggingExited": {},
|
||||
"mac:WindowFileDraggingPerformed": {},
|
||||
"mac:WindowHide": {},
|
||||
"mac:WindowMaximise": {},
|
||||
"mac:WindowUnMaximise": {},
|
||||
"mac:WindowMinimise": {},
|
||||
"mac:WindowUnMinimise": {},
|
||||
"mac:WindowShouldClose": {},
|
||||
"mac:WindowShow": {},
|
||||
"mac:WindowWillBecomeKey": {},
|
||||
"mac:WindowWillBecomeMain": {},
|
||||
"mac:WindowWillBeginSheet": {},
|
||||
"mac:WindowWillChangeOrderingMode": {},
|
||||
"mac:WindowWillClose": {},
|
||||
"mac:WindowWillDeminiaturize": {},
|
||||
"mac:WindowWillEnterFullScreen": {},
|
||||
"mac:WindowWillEnterVersionBrowser": {},
|
||||
"mac:WindowWillExitFullScreen": {},
|
||||
"mac:WindowWillExitVersionBrowser": {},
|
||||
"mac:WindowWillFocus": {},
|
||||
"mac:WindowWillMiniaturize": {},
|
||||
"mac:WindowWillMove": {},
|
||||
"mac:WindowWillOrderOffScreen": {},
|
||||
"mac:WindowWillOrderOnScreen": {},
|
||||
"mac:WindowWillResignMain": {},
|
||||
"mac:WindowWillResize": {},
|
||||
"mac:WindowWillUnfocus": {},
|
||||
"mac:WindowWillUpdate": {},
|
||||
"mac:WindowWillUpdateAlpha": {},
|
||||
"mac:WindowWillUpdateCollectionBehavior": {},
|
||||
"mac:WindowWillUpdateCollectionProperties": {},
|
||||
"mac:WindowWillUpdateShadow": {},
|
||||
"mac:WindowWillUpdateTitle": {},
|
||||
"mac:WindowWillUpdateToolbar": {},
|
||||
"mac:WindowWillUpdateVisibility": {},
|
||||
"mac:WindowWillUseStandardFrame": {},
|
||||
"mac:WindowZoomIn": {},
|
||||
"mac:WindowZoomOut": {},
|
||||
"mac:WindowZoomReset": {},
|
||||
"windows:APMPowerSettingChange": {},
|
||||
"windows:APMPowerStatusChange": {},
|
||||
"windows:APMResumeAutomatic": {},
|
||||
"windows:APMResumeSuspend": {},
|
||||
"windows:APMSuspend": {},
|
||||
"windows:ApplicationStarted": {},
|
||||
"windows:SystemThemeChanged": {},
|
||||
"windows:WebViewNavigationCompleted": {},
|
||||
"windows:WindowActive": {},
|
||||
"windows:WindowBackgroundErase": {},
|
||||
"windows:WindowClickActive": {},
|
||||
"windows:WindowClosing": {},
|
||||
"windows:WindowDidMove": {},
|
||||
"windows:WindowDidResize": {},
|
||||
"windows:WindowDPIChanged": {},
|
||||
"windows:WindowDragDrop": {},
|
||||
"windows:WindowDragEnter": {},
|
||||
"windows:WindowDragLeave": {},
|
||||
"windows:WindowDragOver": {},
|
||||
"windows:WindowEndMove": {},
|
||||
"windows:WindowEndResize": {},
|
||||
"windows:WindowFullscreen": {},
|
||||
"windows:WindowHide": {},
|
||||
"windows:WindowInactive": {},
|
||||
"windows:WindowKeyDown": {},
|
||||
"windows:WindowKeyUp": {},
|
||||
"windows:WindowKillFocus": {},
|
||||
"windows:WindowNonClientHit": {},
|
||||
"windows:WindowNonClientMouseDown": {},
|
||||
"windows:WindowNonClientMouseLeave": {},
|
||||
"windows:WindowNonClientMouseMove": {},
|
||||
"windows:WindowNonClientMouseUp": {},
|
||||
"windows:WindowPaint": {},
|
||||
"windows:WindowRestore": {},
|
||||
"windows:WindowSetFocus": {},
|
||||
"windows:WindowShow": {},
|
||||
"windows:WindowStartMove": {},
|
||||
"windows:WindowStartResize": {},
|
||||
"windows:WindowUnFullscreen": {},
|
||||
"windows:WindowZOrderChanged": {},
|
||||
"windows:WindowMinimise": {},
|
||||
"windows:WindowUnMinimise": {},
|
||||
"windows:WindowMaximise": {},
|
||||
"windows:WindowUnMaximise": {},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,14 +35,38 @@ tasks:
|
|||
cmds:
|
||||
- npx esbuild@latest desktop/@wailsio/runtime/src/index.ts --inject:desktop/compiled/main.js --format=esm --target=safari11 --bundle --ignore-annotations --tree-shaking=true --minify --outfile=../assetserver/bundledassets/runtime.js --define:DEBUG=false --drop:console
|
||||
|
||||
build:all:
|
||||
build:docs:
|
||||
internal: true
|
||||
dir: desktop/@wailsio/runtime
|
||||
deps:
|
||||
- install-deps
|
||||
cmds:
|
||||
- npm run build:docs
|
||||
|
||||
build:docs:md:
|
||||
internal: true
|
||||
dir: desktop/@wailsio/runtime
|
||||
deps:
|
||||
- install-deps
|
||||
cmds:
|
||||
- npm run build:docs:md
|
||||
|
||||
build:runtime:
|
||||
internal: true
|
||||
deps:
|
||||
- build:debug
|
||||
- build:production
|
||||
|
||||
cmds:
|
||||
- cmd: echo "Build Complete."
|
||||
- cmd: echo "Runtime build complete."
|
||||
|
||||
build:all:
|
||||
internal: true
|
||||
cmds:
|
||||
- task: generate:events
|
||||
- task: build:docs
|
||||
- task: build:runtime
|
||||
- echo "Build Complete."
|
||||
|
||||
build:
|
||||
deps:
|
||||
|
|
@ -50,8 +74,39 @@ tasks:
|
|||
cmds:
|
||||
- task: build:all
|
||||
|
||||
docs:
|
||||
summary: Generate TypeDoc documentation for the runtime
|
||||
dir: desktop/@wailsio/runtime
|
||||
deps:
|
||||
- install-deps
|
||||
cmds:
|
||||
- npm run build:docs
|
||||
- echo "Documentation generated at desktop/@wailsio/runtime/docs/"
|
||||
|
||||
docs:md:
|
||||
summary: Generate markdown documentation for the runtime
|
||||
dir: desktop/@wailsio/runtime
|
||||
deps:
|
||||
- install-deps
|
||||
cmds:
|
||||
- npm run build:docs:md
|
||||
- echo "Markdown documentation generated"
|
||||
|
||||
generate:events:
|
||||
dir: ../../tasks/events
|
||||
cmds:
|
||||
- go run generate.go
|
||||
- go fmt ../../pkg/events/events.go
|
||||
|
||||
clean:
|
||||
summary: Clean built artifacts and documentation
|
||||
dir: desktop/@wailsio/runtime
|
||||
cmds:
|
||||
- npm run clean
|
||||
- echo "Cleaned runtime artifacts"
|
||||
|
||||
generate:
|
||||
summary: Generate events only (use runtime:build to rebuild everything)
|
||||
cmds:
|
||||
- task: generate:events
|
||||
- echo "Events generated. Run 'wails3 task runtime:build' to rebuild runtime with updated documentation"
|
||||
|
|
|
|||
|
|
@ -1584,6 +1584,7 @@
|
|||
"integrity": "sha512-HL26ajjMVe/wr3xlzjF0sCPCiAKaZJcIRFZHmG4yKHRJp4YAkHPG5X6GfWxCeDTpOmuHhNiOyNKUoZjjnm0tjw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-mimetype": "^3.0.0"
|
||||
|
|
@ -2561,6 +2562,7 @@
|
|||
"integrity": "sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@gerrit0/mini-shiki": "^1.24.0",
|
||||
"lunr": "^2.3.9",
|
||||
|
|
@ -2633,6 +2635,7 @@
|
|||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
|
@ -2661,6 +2664,7 @@
|
|||
"integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.43",
|
||||
|
|
|
|||
|
|
@ -256,6 +256,5 @@ export const Types = Object.freeze({
|
|||
WindowZoomIn: "common:WindowZoomIn",
|
||||
WindowZoomOut: "common:WindowZoomOut",
|
||||
WindowZoomReset: "common:WindowZoomReset",
|
||||
WindowDropZoneFilesDropped: "common:WindowDropZoneFilesDropped",
|
||||
}),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import * as Flags from "./flags.js";
|
|||
import * as Screens from "./screens.js";
|
||||
import * as System from "./system.js";
|
||||
import * as IOS from "./ios.js";
|
||||
import Window from "./window.js";
|
||||
import Window, { handleDragEnter, handleDragLeave, handleDragOver } from "./window.js";
|
||||
import * as WML from "./wml.js";
|
||||
|
||||
export {
|
||||
|
|
@ -70,4 +70,9 @@ window._wails.invoke = System.invoke;
|
|||
// Binding ensures 'this' correctly refers to the current window instance
|
||||
window._wails.handlePlatformFileDrop = Window.HandlePlatformFileDrop.bind(Window);
|
||||
|
||||
// Linux-specific drag handlers (GTK intercepts DOM drag events)
|
||||
window._wails.handleDragEnter = handleDragEnter;
|
||||
window._wails.handleDragLeave = handleDragLeave;
|
||||
window._wails.handleDragOver = handleDragOver;
|
||||
|
||||
System.invoke("wails:runtime:ready");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ const call = newRuntimeCaller(objectNames.System);
|
|||
const SystemIsDarkMode = 0;
|
||||
const SystemEnvironment = 1;
|
||||
const SystemCapabilities = 2;
|
||||
const ApplicationFilesDroppedWithContext = 100; // New method ID for enriched drop event
|
||||
|
||||
const _invoke = (function () {
|
||||
try {
|
||||
|
|
@ -158,35 +157,3 @@ export function IsDebug(): boolean {
|
|||
return Boolean((window as any)._wails?.environment?.Debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles file drops originating from platform-specific code (e.g., macOS native drag-and-drop).
|
||||
* Gathers information about the drop target element and sends it back to the Go backend.
|
||||
*
|
||||
* @param filenames - An array of file paths (strings) that were dropped.
|
||||
* @param x - The x-coordinate of the drop event.
|
||||
* @param y - The y-coordinate of the drop event.
|
||||
*/
|
||||
export function HandlePlatformFileDrop(filenames: string[], x: number, y: number): void {
|
||||
const element = document.elementFromPoint(x, y);
|
||||
const elementId = element ? element.id : '';
|
||||
const classList = element ? Array.from(element.classList) : [];
|
||||
|
||||
const payload = {
|
||||
filenames,
|
||||
x,
|
||||
y,
|
||||
elementId,
|
||||
classList,
|
||||
};
|
||||
|
||||
call(ApplicationFilesDroppedWithContext, payload)
|
||||
.then(() => {
|
||||
// Optional: Log success or handle if needed
|
||||
console.log("Platform file drop processed and sent to Go.");
|
||||
})
|
||||
.catch(err => {
|
||||
// Optional: Log error
|
||||
console.error("Error sending platform file drop to Go:", err);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ The electron alternative for Go
|
|||
import {newRuntimeCaller, objectNames} from "./runtime.js";
|
||||
import type { Screen } from "./screens.js";
|
||||
|
||||
// NEW: Dropzone constants
|
||||
const DROPZONE_ATTRIBUTE = 'data-wails-dropzone';
|
||||
const DROPZONE_HOVER_CLASS = 'wails-dropzone-hover'; // User can style this class
|
||||
let currentHoveredDropzone: Element | null = null;
|
||||
// Drop target constants
|
||||
const DROP_TARGET_ATTRIBUTE = 'data-file-drop-target';
|
||||
const DROP_TARGET_ACTIVE_CLASS = 'file-drop-target-active';
|
||||
let currentDropTarget: Element | null = null;
|
||||
|
||||
const PositionMethod = 0;
|
||||
const CenterMethod = 1;
|
||||
|
|
@ -66,17 +66,108 @@ const ZoomInMethod = 46;
|
|||
const ZoomOutMethod = 47;
|
||||
const ZoomResetMethod = 48;
|
||||
const SnapAssistMethod = 49;
|
||||
const WindowDropZoneDropped = 50;
|
||||
const FilesDropped = 50;
|
||||
const PrintMethod = 51;
|
||||
|
||||
function getDropzoneElement(element: Element | null): Element | null {
|
||||
/**
|
||||
* Finds the nearest drop target element by walking up the DOM tree.
|
||||
*/
|
||||
function getDropTargetElement(element: Element | null): Element | null {
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
// Allow dropzone attribute to be on the element itself or any parent
|
||||
return element.closest(`[${DROPZONE_ATTRIBUTE}]`);
|
||||
return element.closest(`[${DROP_TARGET_ATTRIBUTE}]`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can use WebView2's postMessageWithAdditionalObjects (Windows)
|
||||
* Also checks that EnableFileDrop is true for this window.
|
||||
*/
|
||||
function canResolveFilePaths(): boolean {
|
||||
// Must have WebView2's postMessageWithAdditionalObjects API (Windows only)
|
||||
if ((window as any).chrome?.webview?.postMessageWithAdditionalObjects == null) {
|
||||
return false;
|
||||
}
|
||||
// Must have EnableFileDrop set to true for this window
|
||||
// This flag is set by the Go backend during runtime initialization
|
||||
return (window as any)._wails?.flags?.enableFileDrop === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send file drop to backend via WebView2 (Windows only)
|
||||
*/
|
||||
function resolveFilePaths(x: number, y: number, files: File[]): void {
|
||||
if ((window as any).chrome?.webview?.postMessageWithAdditionalObjects) {
|
||||
(window as any).chrome.webview.postMessageWithAdditionalObjects(`file:drop:${x}:${y}`, files);
|
||||
}
|
||||
}
|
||||
|
||||
// Native drag state (Linux/macOS intercept DOM drag events)
|
||||
let nativeDragActive = false;
|
||||
|
||||
/**
|
||||
* Cleans up native drag state and hover effects.
|
||||
* Called on drop or when drag leaves the window.
|
||||
*/
|
||||
function cleanupNativeDrag(): void {
|
||||
nativeDragActive = false;
|
||||
if (currentDropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
currentDropTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from Go when a file drag enters the window on Linux/macOS.
|
||||
*/
|
||||
function handleDragEnter(): void {
|
||||
// Check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
return; // File drops disabled, don't activate drag state
|
||||
}
|
||||
nativeDragActive = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from Go when a file drag leaves the window on Linux/macOS.
|
||||
*/
|
||||
function handleDragLeave(): void {
|
||||
cleanupNativeDrag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from Go during file drag to update hover state on Linux/macOS.
|
||||
* @param x - X coordinate in CSS pixels
|
||||
* @param y - Y coordinate in CSS pixels
|
||||
*/
|
||||
function handleDragOver(x: number, y: number): void {
|
||||
if (!nativeDragActive) return;
|
||||
|
||||
// Check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
return; // File drops disabled, don't show hover effects
|
||||
}
|
||||
|
||||
const targetElement = document.elementFromPoint(x, y);
|
||||
const dropTarget = getDropTargetElement(targetElement);
|
||||
|
||||
if (currentDropTarget && currentDropTarget !== dropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
}
|
||||
|
||||
if (dropTarget) {
|
||||
dropTarget.classList.add(DROP_TARGET_ACTIVE_CLASS);
|
||||
currentDropTarget = dropTarget;
|
||||
} else {
|
||||
currentDropTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Export the handlers for use by Go via index.ts
|
||||
export { handleDragEnter, handleDragLeave, handleDragOver };
|
||||
|
||||
/**
|
||||
* A record describing the position of a window.
|
||||
*/
|
||||
|
|
@ -536,33 +627,34 @@ class Window {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles file drops originating from platform-specific code (e.g., macOS native drag-and-drop).
|
||||
* Handles file drops originating from platform-specific code (e.g., macOS/Linux native drag-and-drop).
|
||||
* Gathers information about the drop target element and sends it back to the Go backend.
|
||||
*
|
||||
* @param filenames - An array of file paths (strings) that were dropped.
|
||||
* @param x - The x-coordinate of the drop event.
|
||||
* @param y - The y-coordinate of the drop event.
|
||||
* @param x - The x-coordinate of the drop event (CSS pixels).
|
||||
* @param y - The y-coordinate of the drop event (CSS pixels).
|
||||
*/
|
||||
HandlePlatformFileDrop(filenames: string[], x: number, y: number): void {
|
||||
// Check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
return; // File drops disabled, ignore the drop
|
||||
}
|
||||
|
||||
const element = document.elementFromPoint(x, y);
|
||||
const dropTarget = getDropTargetElement(element);
|
||||
|
||||
// NEW: Check if the drop target is a valid dropzone
|
||||
const dropzoneTarget = getDropzoneElement(element);
|
||||
|
||||
if (!dropzoneTarget) {
|
||||
console.log(`Wails Runtime: Drop on element (or no element) at ${x},${y} which is not a designated dropzone. Ignoring. Element:`, element);
|
||||
// No need to call backend if not a valid dropzone target
|
||||
if (!dropTarget) {
|
||||
// Drop was not on a designated drop target - ignore
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Wails Runtime: Drop on designated dropzone. Element at (${x}, ${y}):`, element, 'Effective dropzone:', dropzoneTarget);
|
||||
const elementDetails = {
|
||||
id: dropzoneTarget.id,
|
||||
classList: Array.from(dropzoneTarget.classList),
|
||||
id: dropTarget.id,
|
||||
classList: Array.from(dropTarget.classList),
|
||||
attributes: {} as { [key: string]: string },
|
||||
};
|
||||
for (let i = 0; i < dropzoneTarget.attributes.length; i++) {
|
||||
const attr = dropzoneTarget.attributes[i];
|
||||
for (let i = 0; i < dropTarget.attributes.length; i++) {
|
||||
const attr = dropTarget.attributes[i];
|
||||
elementDetails.attributes[attr.name] = attr.value;
|
||||
}
|
||||
|
||||
|
|
@ -573,7 +665,10 @@ class Window {
|
|||
elementDetails,
|
||||
};
|
||||
|
||||
this[callerSym](WindowDropZoneDropped, payload);
|
||||
this[callerSym](FilesDropped, payload);
|
||||
|
||||
// Clean up native drag state after drop
|
||||
cleanupNativeDrag();
|
||||
}
|
||||
|
||||
/* Triggers Windows 11 Snap Assist feature (Windows only).
|
||||
|
|
@ -596,81 +691,146 @@ class Window {
|
|||
*/
|
||||
const thisWindow = new Window('');
|
||||
|
||||
// NEW: Global Drag Event Listeners
|
||||
function setupGlobalDropzoneListeners() {
|
||||
/**
|
||||
* Sets up global drag and drop event listeners for file drops.
|
||||
* Handles visual feedback (hover state) and file drop processing.
|
||||
*/
|
||||
function setupDropTargetListeners() {
|
||||
const docElement = document.documentElement;
|
||||
let dragEnterCounter = 0; // To handle dragenter/dragleave on child elements
|
||||
let dragEnterCounter = 0;
|
||||
|
||||
docElement.addEventListener('dragenter', (event) => {
|
||||
event.preventDefault();
|
||||
if (event.dataTransfer && event.dataTransfer.types.includes('Files')) {
|
||||
dragEnterCounter++;
|
||||
const targetElement = document.elementFromPoint(event.clientX, event.clientY);
|
||||
const dropzone = getDropzoneElement(targetElement);
|
||||
if (!event.dataTransfer?.types.includes('Files')) {
|
||||
return; // Only handle file drags, let other drags pass through
|
||||
}
|
||||
event.preventDefault(); // Always prevent default to stop browser navigation
|
||||
// On Windows, check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
event.dataTransfer.dropEffect = 'none'; // Show "no drop" cursor
|
||||
return; // File drops disabled, don't show hover effects
|
||||
}
|
||||
dragEnterCounter++;
|
||||
|
||||
const targetElement = document.elementFromPoint(event.clientX, event.clientY);
|
||||
const dropTarget = getDropTargetElement(targetElement);
|
||||
|
||||
// Clear previous hover regardless, then apply new if valid
|
||||
if (currentHoveredDropzone && currentHoveredDropzone !== dropzone) {
|
||||
currentHoveredDropzone.classList.remove(DROPZONE_HOVER_CLASS);
|
||||
}
|
||||
// Update hover state
|
||||
if (currentDropTarget && currentDropTarget !== dropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
}
|
||||
|
||||
if (dropzone) {
|
||||
dropzone.classList.add(DROPZONE_HOVER_CLASS);
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
currentHoveredDropzone = dropzone;
|
||||
} else {
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
currentHoveredDropzone = null; // Ensure it's cleared if no dropzone found
|
||||
}
|
||||
if (dropTarget) {
|
||||
dropTarget.classList.add(DROP_TARGET_ACTIVE_CLASS);
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
currentDropTarget = dropTarget;
|
||||
} else {
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
currentDropTarget = null;
|
||||
}
|
||||
}, false);
|
||||
|
||||
docElement.addEventListener('dragover', (event) => {
|
||||
event.preventDefault(); // Necessary to allow drop
|
||||
if (event.dataTransfer && event.dataTransfer.types.includes('Files')) {
|
||||
// No need to query elementFromPoint again if already handled by dragenter correctly
|
||||
// Just ensure dropEffect is continuously set based on currentHoveredDropzone
|
||||
if (currentHoveredDropzone) {
|
||||
// Re-apply class just in case it was removed by some other JS
|
||||
if(!currentHoveredDropzone.classList.contains(DROPZONE_HOVER_CLASS)) {
|
||||
currentHoveredDropzone.classList.add(DROPZONE_HOVER_CLASS);
|
||||
}
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
} else {
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
if (!event.dataTransfer?.types.includes('Files')) {
|
||||
return; // Only handle file drags
|
||||
}
|
||||
event.preventDefault(); // Always prevent default to stop browser navigation
|
||||
// On Windows, check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
event.dataTransfer.dropEffect = 'none'; // Show "no drop" cursor
|
||||
return; // File drops disabled, don't show hover effects
|
||||
}
|
||||
|
||||
// Update drop target as cursor moves
|
||||
const targetElement = document.elementFromPoint(event.clientX, event.clientY);
|
||||
const dropTarget = getDropTargetElement(targetElement);
|
||||
|
||||
if (currentDropTarget && currentDropTarget !== dropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
}
|
||||
|
||||
if (dropTarget) {
|
||||
if (!dropTarget.classList.contains(DROP_TARGET_ACTIVE_CLASS)) {
|
||||
dropTarget.classList.add(DROP_TARGET_ACTIVE_CLASS);
|
||||
}
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
currentDropTarget = dropTarget;
|
||||
} else {
|
||||
event.dataTransfer.dropEffect = 'none';
|
||||
currentDropTarget = null;
|
||||
}
|
||||
}, false);
|
||||
|
||||
docElement.addEventListener('dragleave', (event) => {
|
||||
event.preventDefault();
|
||||
if (event.dataTransfer && event.dataTransfer.types.includes('Files')) {
|
||||
dragEnterCounter--;
|
||||
// Only remove hover if drag truly left the window or the last dropzone
|
||||
if (dragEnterCounter === 0 || event.relatedTarget === null || (currentHoveredDropzone && !currentHoveredDropzone.contains(event.relatedTarget as Node))) {
|
||||
if (currentHoveredDropzone) {
|
||||
currentHoveredDropzone.classList.remove(DROPZONE_HOVER_CLASS);
|
||||
currentHoveredDropzone = null;
|
||||
}
|
||||
dragEnterCounter = 0; // Reset counter if it went negative or left window
|
||||
if (!event.dataTransfer?.types.includes('Files')) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault(); // Always prevent default to stop browser navigation
|
||||
// On Windows, check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// On Linux/WebKitGTK and macOS, dragleave fires immediately with relatedTarget=null when native
|
||||
// drag handling is involved. Ignore these spurious events - we'll clean up on drop instead.
|
||||
if (event.relatedTarget === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
dragEnterCounter--;
|
||||
|
||||
if (dragEnterCounter === 0 ||
|
||||
(currentDropTarget && !currentDropTarget.contains(event.relatedTarget as Node))) {
|
||||
if (currentDropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
currentDropTarget = null;
|
||||
}
|
||||
dragEnterCounter = 0;
|
||||
}
|
||||
}, false);
|
||||
|
||||
docElement.addEventListener('drop', (event) => {
|
||||
event.preventDefault(); // Prevent default browser file handling
|
||||
dragEnterCounter = 0; // Reset counter
|
||||
if (currentHoveredDropzone) {
|
||||
currentHoveredDropzone.classList.remove(DROPZONE_HOVER_CLASS);
|
||||
currentHoveredDropzone = null;
|
||||
if (!event.dataTransfer?.types.includes('Files')) {
|
||||
return; // Only handle file drops
|
||||
}
|
||||
event.preventDefault(); // Always prevent default to stop browser navigation
|
||||
// On Windows, check if file drops are enabled for this window
|
||||
if ((window as any)._wails?.flags?.enableFileDrop === false) {
|
||||
return;
|
||||
}
|
||||
dragEnterCounter = 0;
|
||||
|
||||
if (currentDropTarget) {
|
||||
currentDropTarget.classList.remove(DROP_TARGET_ACTIVE_CLASS);
|
||||
currentDropTarget = null;
|
||||
}
|
||||
|
||||
// On Windows, handle file drops via JavaScript
|
||||
// On macOS/Linux, native code will call HandlePlatformFileDrop
|
||||
if (canResolveFilePaths()) {
|
||||
const files: File[] = [];
|
||||
if (event.dataTransfer.items) {
|
||||
for (const item of event.dataTransfer.items) {
|
||||
if (item.kind === 'file') {
|
||||
const file = item.getAsFile();
|
||||
if (file) files.push(file);
|
||||
}
|
||||
}
|
||||
} else if (event.dataTransfer.files) {
|
||||
for (const file of event.dataTransfer.files) {
|
||||
files.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
resolveFilePaths(event.clientX, event.clientY, files);
|
||||
}
|
||||
}
|
||||
// The actual drop processing is initiated by the native side calling HandlePlatformFileDrop
|
||||
// HandlePlatformFileDrop will then check if the drop was on a valid zone.
|
||||
}, false);
|
||||
}
|
||||
|
||||
// Initialize listeners when the script loads
|
||||
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
||||
setupGlobalDropzoneListeners();
|
||||
setupDropTargetListeners();
|
||||
}
|
||||
|
||||
export default thisWindow;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
json "github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
var runtimeInit = `window._wails=window._wails||{};window.wails=window.wails||{};`
|
||||
var runtimeInit = `window._wails=window._wails||{};window._wails.flags=window._wails.flags||{};window.wails=window.wails||{};`
|
||||
|
||||
func Core(flags map[string]any) string {
|
||||
flagsStr := ""
|
||||
|
|
|
|||
|
|
@ -239,9 +239,9 @@ type OriginInfo struct {
|
|||
|
||||
var windowMessageBuffer = make(chan *windowMessage, 5)
|
||||
|
||||
// DropZoneDetails contains information about the HTML element
|
||||
// at the location of a file drop.
|
||||
type DropZoneDetails struct {
|
||||
// DropTargetDetails contains information about the HTML element
|
||||
// where files were dropped (the element with data-file-drop-target attribute).
|
||||
type DropTargetDetails struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
ElementID string `json:"id"`
|
||||
|
|
@ -250,20 +250,20 @@ type DropZoneDetails struct {
|
|||
}
|
||||
|
||||
type dragAndDropMessage struct {
|
||||
windowId uint
|
||||
filenames []string
|
||||
X int
|
||||
Y int
|
||||
DropZone *DropZoneDetails
|
||||
windowId uint
|
||||
filenames []string
|
||||
X int
|
||||
Y int
|
||||
DropTarget *DropTargetDetails
|
||||
}
|
||||
|
||||
var windowDragAndDropBuffer = make(chan *dragAndDropMessage, 5)
|
||||
|
||||
func addDragAndDropMessage(windowId uint, filenames []string, dropZone *DropZoneDetails) {
|
||||
func addDragAndDropMessage(windowId uint, filenames []string, dropTarget *DropTargetDetails) {
|
||||
windowDragAndDropBuffer <- &dragAndDropMessage{
|
||||
windowId: windowId,
|
||||
filenames: filenames,
|
||||
DropZone: dropZone,
|
||||
windowId: windowId,
|
||||
filenames: filenames,
|
||||
DropTarget: dropTarget,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -619,11 +619,6 @@ func (a *App) Run() error {
|
|||
go func() {
|
||||
for {
|
||||
dragAndDropMessage := <-windowDragAndDropBuffer
|
||||
a.Logger.Debug(
|
||||
"[DragDropDebug] App.Run: Received message from windowDragAndDropBuffer",
|
||||
"message",
|
||||
fmt.Sprintf("%+v", dragAndDropMessage),
|
||||
)
|
||||
go a.handleDragAndDropMessage(dragAndDropMessage)
|
||||
}
|
||||
}()
|
||||
|
|
@ -715,13 +710,7 @@ func (a *App) shutdownServices() {
|
|||
}
|
||||
|
||||
func (a *App) handleDragAndDropMessage(event *dragAndDropMessage) {
|
||||
a.Logger.Debug(
|
||||
"[DragDropDebug] App.handleDragAndDropMessage: Called with event",
|
||||
"event",
|
||||
fmt.Sprintf("%+v", event),
|
||||
)
|
||||
defer handlePanic()
|
||||
// Get window from window map
|
||||
a.windowsLock.Lock()
|
||||
window, ok := a.windows[event.windowId]
|
||||
a.windowsLock.Unlock()
|
||||
|
|
@ -729,13 +718,7 @@ func (a *App) handleDragAndDropMessage(event *dragAndDropMessage) {
|
|||
a.warning("WebviewWindow #%d not found", event.windowId)
|
||||
return
|
||||
}
|
||||
// Get callback from window
|
||||
a.Logger.Debug(
|
||||
"[DragDropDebug] App.handleDragAndDropMessage: Calling window.HandleDragAndDropMessage",
|
||||
"windowID",
|
||||
event.windowId,
|
||||
)
|
||||
window.HandleDragAndDropMessage(event.filenames, event.DropZone)
|
||||
window.handleDragAndDropMessage(event.filenames, event.DropTarget)
|
||||
}
|
||||
|
||||
func (a *App) handleWindowMessage(event *windowMessage) {
|
||||
|
|
|
|||
|
|
@ -196,6 +196,8 @@ static void startSingleInstanceListener(const char *uniqueID) {
|
|||
*/
|
||||
import "C"
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
json "github.com/goccy/go-json"
|
||||
|
|
@ -414,6 +416,254 @@ func processDragItems(windowID C.uint, arr **C.char, length C.int, x C.int, y C.
|
|||
targetWindow.InitiateFrontendDropProcessing(filenames, int(x), int(y))
|
||||
}
|
||||
|
||||
//export macosOnDragEnter
|
||||
func macosOnDragEnter(windowID C.uint) {
|
||||
window, ok := globalApplication.Window.GetByID(uint(windowID))
|
||||
if !ok || window == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Call JavaScript to show drag entered state
|
||||
window.ExecJS("window._wails.handleDragEnter();")
|
||||
}
|
||||
|
||||
//export macosOnDragExit
|
||||
func macosOnDragExit(windowID C.uint) {
|
||||
window, ok := globalApplication.Window.GetByID(uint(windowID))
|
||||
if !ok || window == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Call JavaScript to clean up drag state
|
||||
window.ExecJS("window._wails.handleDragLeave();")
|
||||
}
|
||||
|
||||
var (
|
||||
// Pre-allocated buffer for drag JS calls to avoid allocations
|
||||
dragOverJSBuffer = make([]byte, 128) // Increased for safety
|
||||
dragOverJSMutex sync.Mutex // Protects dragOverJSBuffer
|
||||
dragOverJSPrefix = []byte("window._wails.handleDragOver(")
|
||||
|
||||
// Cache window references to avoid repeated lookups
|
||||
windowImplCache sync.Map // windowID -> *macosWebviewWindow
|
||||
|
||||
// Per-window drag throttle state
|
||||
dragThrottle sync.Map // windowID -> *dragThrottleState
|
||||
)
|
||||
|
||||
type dragThrottleState struct {
|
||||
mu sync.Mutex // Protects all fields below
|
||||
lastX, lastY int
|
||||
timer *time.Timer
|
||||
pendingX int
|
||||
pendingY int
|
||||
hasPending bool
|
||||
}
|
||||
|
||||
// clearWindowDragCache removes cached references for a window
|
||||
func clearWindowDragCache(windowID uint) {
|
||||
windowImplCache.Delete(windowID)
|
||||
|
||||
// Cancel any pending timer
|
||||
if throttleVal, ok := dragThrottle.Load(windowID); ok {
|
||||
if throttle, ok := throttleVal.(*dragThrottleState); ok {
|
||||
throttle.mu.Lock()
|
||||
if throttle.timer != nil {
|
||||
throttle.timer.Stop()
|
||||
}
|
||||
throttle.mu.Unlock()
|
||||
}
|
||||
}
|
||||
dragThrottle.Delete(windowID)
|
||||
}
|
||||
|
||||
// writeInt writes an integer to a byte slice and returns the number of bytes written
|
||||
func writeInt(buf []byte, n int) int {
|
||||
if n < 0 {
|
||||
if len(buf) == 0 {
|
||||
return 0
|
||||
}
|
||||
buf[0] = '-'
|
||||
return 1 + writeInt(buf[1:], -n)
|
||||
}
|
||||
if n == 0 {
|
||||
if len(buf) == 0 {
|
||||
return 0
|
||||
}
|
||||
buf[0] = '0'
|
||||
return 1
|
||||
}
|
||||
|
||||
// Count digits
|
||||
tmp := n
|
||||
digits := 0
|
||||
for tmp > 0 {
|
||||
digits++
|
||||
tmp /= 10
|
||||
}
|
||||
|
||||
// Bounds check
|
||||
if digits > len(buf) {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Write digits in reverse
|
||||
for i := digits - 1; i >= 0; i-- {
|
||||
buf[i] = byte('0' + n%10)
|
||||
n /= 10
|
||||
}
|
||||
return digits
|
||||
}
|
||||
|
||||
//export macosOnDragOver
|
||||
func macosOnDragOver(windowID C.uint, x C.int, y C.int) {
|
||||
winID := uint(windowID)
|
||||
intX, intY := int(x), int(y)
|
||||
|
||||
// Get or create throttle state
|
||||
throttleKey := winID
|
||||
throttleVal, _ := dragThrottle.LoadOrStore(throttleKey, &dragThrottleState{
|
||||
lastX: intX,
|
||||
lastY: intY,
|
||||
})
|
||||
throttle := throttleVal.(*dragThrottleState)
|
||||
|
||||
throttle.mu.Lock()
|
||||
|
||||
// Update pending position
|
||||
throttle.pendingX = intX
|
||||
throttle.pendingY = intY
|
||||
throttle.hasPending = true
|
||||
|
||||
// If timer is already running, just update the pending position
|
||||
if throttle.timer != nil {
|
||||
throttle.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Apply 5-pixel threshold for immediate update
|
||||
dx := intX - throttle.lastX
|
||||
dy := intY - throttle.lastY
|
||||
if dx < 0 {
|
||||
dx = -dx
|
||||
}
|
||||
if dy < 0 {
|
||||
dy = -dy
|
||||
}
|
||||
|
||||
// Check if we should send an immediate update
|
||||
shouldSendNow := dx >= 5 || dy >= 5
|
||||
|
||||
if shouldSendNow {
|
||||
// Update last position
|
||||
throttle.lastX = intX
|
||||
throttle.lastY = intY
|
||||
throttle.hasPending = false
|
||||
|
||||
// Send this update immediately (unlock before JS call to avoid deadlock)
|
||||
throttle.mu.Unlock()
|
||||
sendDragUpdate(winID, intX, intY)
|
||||
throttle.mu.Lock()
|
||||
}
|
||||
|
||||
// Start 50ms timer for next update (whether we sent now or not)
|
||||
throttle.timer = time.AfterFunc(50*time.Millisecond, func() {
|
||||
// Execute on main thread to ensure UI updates
|
||||
InvokeSync(func() {
|
||||
throttle.mu.Lock()
|
||||
// Clear timer reference
|
||||
throttle.timer = nil
|
||||
|
||||
// Send pending update if any
|
||||
if throttle.hasPending {
|
||||
pendingX, pendingY := throttle.pendingX, throttle.pendingY
|
||||
throttle.lastX = pendingX
|
||||
throttle.lastY = pendingY
|
||||
throttle.hasPending = false
|
||||
throttle.mu.Unlock()
|
||||
sendDragUpdate(winID, pendingX, pendingY)
|
||||
} else {
|
||||
throttle.mu.Unlock()
|
||||
}
|
||||
})
|
||||
})
|
||||
throttle.mu.Unlock()
|
||||
}
|
||||
|
||||
// sendDragUpdate sends the actual drag update to JavaScript
|
||||
func sendDragUpdate(winID uint, x, y int) {
|
||||
// Try cached implementation first
|
||||
var darwinImpl *macosWebviewWindow
|
||||
var needsExecJS bool
|
||||
|
||||
if cached, found := windowImplCache.Load(winID); found {
|
||||
darwinImpl = cached.(*macosWebviewWindow)
|
||||
if darwinImpl != nil && darwinImpl.nsWindow != nil {
|
||||
needsExecJS = true
|
||||
} else {
|
||||
// Invalid cache entry, remove it
|
||||
windowImplCache.Delete(winID)
|
||||
}
|
||||
}
|
||||
|
||||
if !needsExecJS {
|
||||
// Fallback to full lookup
|
||||
window, ok := globalApplication.Window.GetByID(winID)
|
||||
if !ok || window == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Type assert to WebviewWindow
|
||||
webviewWindow, ok := window.(*WebviewWindow)
|
||||
if !ok || webviewWindow == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Get implementation
|
||||
darwinImpl, ok = webviewWindow.impl.(*macosWebviewWindow)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Cache for next time
|
||||
windowImplCache.Store(winID, darwinImpl)
|
||||
needsExecJS = true
|
||||
}
|
||||
|
||||
if !needsExecJS || darwinImpl == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Protect shared buffer access
|
||||
dragOverJSMutex.Lock()
|
||||
|
||||
// Build JS string with zero allocations
|
||||
// Format: "window._wails.handleDragOver(X,Y)"
|
||||
// Max length with int32 coords: 30 + 11 + 1 + 11 + 1 + 1 = 55 bytes
|
||||
n := copy(dragOverJSBuffer[:], dragOverJSPrefix)
|
||||
n += writeInt(dragOverJSBuffer[n:], x)
|
||||
if n < len(dragOverJSBuffer) {
|
||||
dragOverJSBuffer[n] = ','
|
||||
n++
|
||||
}
|
||||
n += writeInt(dragOverJSBuffer[n:], y)
|
||||
if n < len(dragOverJSBuffer) {
|
||||
dragOverJSBuffer[n] = ')'
|
||||
n++
|
||||
}
|
||||
if n < len(dragOverJSBuffer) {
|
||||
dragOverJSBuffer[n] = 0 // null terminate for C
|
||||
} else {
|
||||
// Buffer overflow - this should not happen with 128 byte buffer
|
||||
dragOverJSMutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Call JavaScript with zero allocations
|
||||
darwinImpl.execJSDragOver(dragOverJSBuffer[:n+1]) // Include null terminator
|
||||
dragOverJSMutex.Unlock()
|
||||
}
|
||||
|
||||
//export processMenuItemClick
|
||||
func processMenuItemClick(menuID C.uint) {
|
||||
menuItemClicked <- uint(menuID)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package application
|
|||
var blankWindowEventContext = &WindowEventContext{}
|
||||
|
||||
const (
|
||||
droppedFiles = "droppedFiles"
|
||||
dropZoneDetailsKey = "dropZoneDetails"
|
||||
droppedFiles = "droppedFiles"
|
||||
dropTargetDetailsKey = "dropTargetDetails"
|
||||
)
|
||||
|
||||
type WindowEventContext struct {
|
||||
|
|
@ -42,33 +42,31 @@ func (c WindowEventContext) setCoordinates(x, y int) {
|
|||
c.data["y"] = y
|
||||
}
|
||||
|
||||
func (c WindowEventContext) setDropZoneDetails(details *DropZoneDetails) {
|
||||
func (c WindowEventContext) setDropTargetDetails(details *DropTargetDetails) {
|
||||
if c.data == nil {
|
||||
c.data = make(map[string]any)
|
||||
}
|
||||
if details == nil {
|
||||
c.data[dropZoneDetailsKey] = nil
|
||||
c.data[dropTargetDetailsKey] = nil
|
||||
return
|
||||
}
|
||||
c.data[dropZoneDetailsKey] = details
|
||||
c.data[dropTargetDetailsKey] = details
|
||||
}
|
||||
|
||||
// DropZoneDetails retrieves the detailed drop zone information, if available.
|
||||
func (c WindowEventContext) DropZoneDetails() *DropZoneDetails {
|
||||
// DropTargetDetails retrieves information about the drop target element.
|
||||
func (c WindowEventContext) DropTargetDetails() *DropTargetDetails {
|
||||
if c.data == nil {
|
||||
c.data = make(map[string]any)
|
||||
}
|
||||
details, ok := c.data[dropZoneDetailsKey]
|
||||
details, ok := c.data[dropTargetDetailsKey]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// Explicitly type assert, handle if it's nil (though setDropZoneDetails should handle it)
|
||||
if details == nil {
|
||||
return nil
|
||||
}
|
||||
result, ok := details.(*DropZoneDetails)
|
||||
result, ok := details.(*DropTargetDetails)
|
||||
if !ok {
|
||||
// This case indicates a programming error if data was set incorrectly
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@ import (
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#ifdef G_APPLICATION_DEFAULT_FLAGS
|
||||
#define APPLICATION_DEFAULT_FLAGS G_APPLICATION_DEFAULT_FLAGS
|
||||
#else
|
||||
#define APPLICATION_DEFAULT_FLAGS G_APPLICATION_FLAGS_NONE
|
||||
#endif
|
||||
// Use NON_UNIQUE to allow multiple instances of the application to run.
|
||||
// This matches the behavior of gtk_init/gtk_main used in v2.
|
||||
#define APPLICATION_DEFAULT_FLAGS G_APPLICATION_NON_UNIQUE
|
||||
|
||||
typedef struct CallbackID
|
||||
{
|
||||
|
|
@ -87,6 +85,9 @@ void handleClick(void*);
|
|||
extern gboolean onButtonEvent(GtkWidget *widget, GdkEventButton *event, uintptr_t user_data);
|
||||
extern gboolean onMenuButtonEvent(GtkWidget *widget, GdkEventButton *event, uintptr_t user_data);
|
||||
extern void onUriList(char **extracted, gint x, gint y, gpointer data);
|
||||
extern void onDragEnter(gpointer data);
|
||||
extern void onDragLeave(gpointer data);
|
||||
extern void onDragOver(gint x, gint y, gpointer data);
|
||||
extern gboolean onKeyPressEvent (GtkWidget *widget, GdkEventKey *event, uintptr_t user_data);
|
||||
extern void onProcessRequest(WebKitURISchemeRequest *request, uintptr_t user_data);
|
||||
extern void sendMessageToBackend(WebKitUserContentManager *contentManager, WebKitJavascriptResult *result, void *data);
|
||||
|
|
@ -224,34 +225,204 @@ static int GetNumScreens(){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void on_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
// Handle file drops from the OS - called when drag data is received
|
||||
static void on_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
GtkSelectionData *selection_data, guint target_type, guint time,
|
||||
gpointer data)
|
||||
{
|
||||
gint length = gtk_selection_data_get_length(selection_data);
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
g_print("DnD failed!\n");
|
||||
gtk_drag_finish(context, FALSE, FALSE, time);
|
||||
// Only process target_type 2 which is our text/uri-list
|
||||
// Other target types are from internal WebKit drags
|
||||
if (target_type != 2) {
|
||||
return; // Don't interfere with internal drags
|
||||
}
|
||||
|
||||
gchar *uri_data = (gchar *)gtk_selection_data_get_data(selection_data);
|
||||
gchar **uri_list = g_uri_list_extract_uris(uri_data);
|
||||
// Check if we have valid data
|
||||
if (selection_data == NULL || gtk_selection_data_get_length(selection_data) <= 0) {
|
||||
gtk_drag_finish(context, FALSE, FALSE, time);
|
||||
return;
|
||||
}
|
||||
|
||||
onUriList(uri_list, x, y, data);
|
||||
const gchar *uri_data = (const gchar *)gtk_selection_data_get_data(selection_data);
|
||||
gchar **filenames = g_uri_list_extract_uris(uri_data);
|
||||
if (filenames == NULL || filenames[0] == NULL) {
|
||||
if (filenames) g_strfreev(filenames);
|
||||
gtk_drag_finish(context, FALSE, FALSE, time);
|
||||
return;
|
||||
}
|
||||
|
||||
g_strfreev(uri_list);
|
||||
gtk_drag_finish(context, TRUE, TRUE, time);
|
||||
// Build file array for Go
|
||||
GPtrArray *file_array = g_ptr_array_new();
|
||||
int iter = 0;
|
||||
while (filenames[iter] != NULL) {
|
||||
char *filename = g_filename_from_uri(filenames[iter], NULL, NULL);
|
||||
if (filename != NULL) {
|
||||
g_ptr_array_add(file_array, filename);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
g_strfreev(filenames);
|
||||
|
||||
if (file_array->len > 0) {
|
||||
// Get stored drop coordinates and data pointer
|
||||
gint drop_x = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "drop-x"));
|
||||
gint drop_y = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "drop-y"));
|
||||
gpointer drop_data = g_object_get_data(G_OBJECT(widget), "drop-data");
|
||||
|
||||
// Add NULL terminator and call Go
|
||||
g_ptr_array_add(file_array, NULL);
|
||||
onUriList((gchar **)file_array->pdata, drop_x, drop_y, drop_data);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
for (guint i = 0; i < file_array->len; i++) {
|
||||
gpointer item = g_ptr_array_index(file_array, i);
|
||||
if (item) g_free(item);
|
||||
}
|
||||
g_ptr_array_free(file_array, TRUE);
|
||||
|
||||
// Finish the drag successfully to prevent WebKit from opening the file
|
||||
gtk_drag_finish(context, TRUE, FALSE, time);
|
||||
}
|
||||
|
||||
// drag and drop tutorial: https://wiki.gnome.org/Newcomers/OldDragNDropTutorial
|
||||
// Track if we've notified about drag entering
|
||||
static gboolean drag_entered = FALSE;
|
||||
|
||||
// Track if a drag started from within the webview (internal HTML5 drag)
|
||||
static gboolean internal_drag_active = FALSE;
|
||||
|
||||
// Called when a drag starts FROM this widget (internal drag)
|
||||
static void on_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
|
||||
{
|
||||
internal_drag_active = TRUE;
|
||||
}
|
||||
|
||||
// Called when a drag that started from this widget ends
|
||||
static void on_drag_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
|
||||
{
|
||||
internal_drag_active = FALSE;
|
||||
}
|
||||
|
||||
// Check if a drag context contains file URIs (external drop)
|
||||
// Returns TRUE only for external file manager drops, FALSE for internal HTML5 drags
|
||||
static gboolean is_file_drag(GdkDragContext *context)
|
||||
{
|
||||
GList *targets = gdk_drag_context_list_targets(context);
|
||||
|
||||
// Internal HTML5 drags have WebKit-specific targets, external file drops have text/uri-list
|
||||
for (GList *l = targets; l != NULL; l = l->next) {
|
||||
GdkAtom atom = GDK_POINTER_TO_ATOM(l->data);
|
||||
gchar *name = gdk_atom_name(atom);
|
||||
if (name) {
|
||||
gboolean is_uri = g_strcmp0(name, "text/uri-list") == 0;
|
||||
g_free(name);
|
||||
if (is_uri) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Handle the actual drop - called when user releases mouse button
|
||||
static gboolean on_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer data)
|
||||
{
|
||||
// Only handle external file drops, let WebKit handle internal HTML5 drags
|
||||
if (!is_file_drag(context)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Reset drag entered state
|
||||
drag_entered = FALSE;
|
||||
|
||||
// Store coordinates for use in drag-data-received
|
||||
g_object_set_data(G_OBJECT(widget), "drop-x", GINT_TO_POINTER(x));
|
||||
g_object_set_data(G_OBJECT(widget), "drop-y", GINT_TO_POINTER(y));
|
||||
g_object_set_data(G_OBJECT(widget), "drop-data", data);
|
||||
|
||||
// Request the file data - this triggers drag-data-received
|
||||
GdkAtom target = gdk_atom_intern("text/uri-list", FALSE);
|
||||
gtk_drag_get_data(widget, context, target, time);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Handle drag-motion for hover effects on external file drags
|
||||
static gboolean on_drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
|
||||
{
|
||||
// Don't handle internal HTML5 drags
|
||||
if (internal_drag_active || !is_file_drag(context)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_drag_status(context, GDK_ACTION_COPY, time);
|
||||
|
||||
// Notify JS once when drag enters
|
||||
if (!drag_entered) {
|
||||
drag_entered = TRUE;
|
||||
onDragEnter(data);
|
||||
}
|
||||
|
||||
// Send position to JS for hover effects (Go side throttles this)
|
||||
onDragOver(x, y, data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Handle drag-leave - drag exited the window
|
||||
static void on_drag_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
|
||||
{
|
||||
// Don't handle internal HTML5 drags
|
||||
if (internal_drag_active || !is_file_drag(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drag_entered) {
|
||||
drag_entered = FALSE;
|
||||
onDragLeave(data);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up drag and drop handlers for external file drops with hover effects
|
||||
static void enableDND(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
GtkTargetEntry *target = gtk_target_entry_new("text/uri-list", 0, 0);
|
||||
gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target, 1, GDK_ACTION_COPY);
|
||||
// Core handlers for file drop
|
||||
g_signal_connect(G_OBJECT(widget), "drag-data-received", G_CALLBACK(on_drag_data_received), data);
|
||||
g_signal_connect(G_OBJECT(widget), "drag-drop", G_CALLBACK(on_drag_drop), data);
|
||||
|
||||
signal_connect(widget, "drag-data-received", on_data_received, data);
|
||||
// Hover effect handlers - return FALSE for internal drags to let WebKit handle them
|
||||
g_signal_connect(G_OBJECT(widget), "drag-motion", G_CALLBACK(on_drag_motion), data);
|
||||
g_signal_connect(G_OBJECT(widget), "drag-leave", G_CALLBACK(on_drag_leave), data);
|
||||
}
|
||||
|
||||
// Block external file drops - consume the events to prevent WebKit from navigating to files
|
||||
// Returns TRUE for file drags to consume them, FALSE for internal HTML5 drags to let WebKit handle
|
||||
static gboolean on_drag_drop_blocked(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
|
||||
guint time, gpointer data)
|
||||
{
|
||||
if (!is_file_drag(context)) {
|
||||
return FALSE; // Let WebKit handle internal HTML5 drags
|
||||
}
|
||||
// Block external file drops by finishing with failure
|
||||
gtk_drag_finish(context, FALSE, FALSE, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean on_drag_motion_blocked(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
|
||||
{
|
||||
if (internal_drag_active || !is_file_drag(context)) {
|
||||
return FALSE; // Let WebKit handle internal HTML5 drags
|
||||
}
|
||||
// Show "no drop" cursor for external file drags
|
||||
gdk_drag_status(context, 0, time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Set up handlers that block external file drops while allowing internal HTML5 drag-and-drop
|
||||
static void disableDND(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
g_signal_connect(G_OBJECT(widget), "drag-drop", G_CALLBACK(on_drag_drop_blocked), data);
|
||||
g_signal_connect(G_OBJECT(widget), "drag-motion", G_CALLBACK(on_drag_motion_blocked), data);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
|
@ -848,10 +1019,15 @@ func (w *linuxWebviewWindow) close() {
|
|||
}
|
||||
|
||||
func (w *linuxWebviewWindow) enableDND() {
|
||||
C.gtk_drag_dest_unset((*C.GtkWidget)(w.webview))
|
||||
// Pass window ID as pointer value (not pointer to ID) - same pattern as other signal handlers
|
||||
winID := unsafe.Pointer(uintptr(w.parent.id))
|
||||
C.enableDND((*C.GtkWidget)(w.webview), C.gpointer(winID))
|
||||
}
|
||||
|
||||
windowId := C.uint(w.parent.id)
|
||||
C.enableDND((*C.GtkWidget)(w.vbox), C.gpointer(&windowId))
|
||||
func (w *linuxWebviewWindow) disableDND() {
|
||||
// Block external file drops while allowing internal HTML5 drag-and-drop
|
||||
winID := unsafe.Pointer(uintptr(w.parent.id))
|
||||
C.disableDND((*C.GtkWidget)(w.webview), C.gpointer(winID))
|
||||
}
|
||||
|
||||
func (w *linuxWebviewWindow) execJS(js string) {
|
||||
|
|
@ -869,6 +1045,61 @@ func (w *linuxWebviewWindow) execJS(js string) {
|
|||
})
|
||||
}
|
||||
|
||||
// Preallocated buffer for drag-over JS calls to avoid allocations
|
||||
// "window._wails.handleDragOver(XXXXX,YYYYY)" is max ~45 chars
|
||||
var dragOverJSBuffer = C.CString(strings.Repeat(" ", 64))
|
||||
var emptyWorldName = C.CString("")
|
||||
|
||||
// execJSDragOver executes JS for drag-over events with zero Go allocations.
|
||||
// It directly writes to a preallocated C buffer. Must be called from main thread.
|
||||
func (w *linuxWebviewWindow) execJSDragOver(x, y int) {
|
||||
// Format: "window._wails.handleDragOver(X,Y)"
|
||||
// Write directly to C buffer
|
||||
buf := (*[64]byte)(unsafe.Pointer(dragOverJSBuffer))
|
||||
n := copy(buf[:], "window._wails.handleDragOver(")
|
||||
n += writeInt(buf[n:], x)
|
||||
buf[n] = ','
|
||||
n++
|
||||
n += writeInt(buf[n:], y)
|
||||
buf[n] = ')'
|
||||
n++
|
||||
buf[n] = 0 // null terminate
|
||||
|
||||
C.webkit_web_view_evaluate_javascript(w.webKitWebView(),
|
||||
dragOverJSBuffer,
|
||||
C.long(n),
|
||||
nil,
|
||||
emptyWorldName,
|
||||
nil,
|
||||
nil,
|
||||
nil)
|
||||
}
|
||||
|
||||
// writeInt writes an integer to a byte slice and returns the number of bytes written
|
||||
func writeInt(buf []byte, n int) int {
|
||||
if n < 0 {
|
||||
buf[0] = '-'
|
||||
return 1 + writeInt(buf[1:], -n)
|
||||
}
|
||||
if n == 0 {
|
||||
buf[0] = '0'
|
||||
return 1
|
||||
}
|
||||
// Count digits
|
||||
tmp := n
|
||||
digits := 0
|
||||
for tmp > 0 {
|
||||
digits++
|
||||
tmp /= 10
|
||||
}
|
||||
// Write digits in reverse
|
||||
for i := digits - 1; i >= 0; i-- {
|
||||
buf[i] = byte('0' + n%10)
|
||||
n /= 10
|
||||
}
|
||||
return digits
|
||||
}
|
||||
|
||||
func getMousePosition() (int, int, *Screen) {
|
||||
var x, y C.gint
|
||||
var screen *C.GdkScreen
|
||||
|
|
@ -1568,6 +1799,45 @@ func onMenuButtonEvent(_ *C.GtkWidget, event *C.GdkEventButton, data C.uintptr_t
|
|||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
//export onDragEnter
|
||||
func onDragEnter(data unsafe.Pointer) {
|
||||
windowId := uint(uintptr(data))
|
||||
targetWindow, ok := globalApplication.Window.GetByID(windowId)
|
||||
if !ok || targetWindow == nil {
|
||||
return
|
||||
}
|
||||
// HandleDragEnter is Linux-specific (GTK intercepts drag events)
|
||||
if w, ok := targetWindow.(*WebviewWindow); ok {
|
||||
w.HandleDragEnter()
|
||||
}
|
||||
}
|
||||
|
||||
//export onDragLeave
|
||||
func onDragLeave(data unsafe.Pointer) {
|
||||
windowId := uint(uintptr(data))
|
||||
targetWindow, ok := globalApplication.Window.GetByID(windowId)
|
||||
if !ok || targetWindow == nil {
|
||||
return
|
||||
}
|
||||
// HandleDragLeave is Linux-specific (GTK intercepts drag events)
|
||||
if w, ok := targetWindow.(*WebviewWindow); ok {
|
||||
w.HandleDragLeave()
|
||||
}
|
||||
}
|
||||
|
||||
//export onDragOver
|
||||
func onDragOver(x C.gint, y C.gint, data unsafe.Pointer) {
|
||||
windowId := uint(uintptr(data))
|
||||
targetWindow, ok := globalApplication.Window.GetByID(windowId)
|
||||
if !ok || targetWindow == nil {
|
||||
return
|
||||
}
|
||||
// HandleDragOver is Linux-specific (GTK intercepts drag events)
|
||||
if w, ok := targetWindow.(*WebviewWindow); ok {
|
||||
w.HandleDragOver(int(x), int(y))
|
||||
}
|
||||
}
|
||||
|
||||
//export onUriList
|
||||
func onUriList(extracted **C.char, x C.gint, y C.gint, data unsafe.Pointer) {
|
||||
// Credit: https://groups.google.com/g/golang-nuts/c/bI17Bpck8K4/m/DVDa7EMtDAAJ
|
||||
|
|
@ -1578,12 +1848,17 @@ func onUriList(extracted **C.char, x C.gint, y C.gint, data unsafe.Pointer) {
|
|||
extracted = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(extracted)) + offset))
|
||||
}
|
||||
|
||||
windowDragAndDropBuffer <- &dragAndDropMessage{
|
||||
windowId: uint(*((*C.uint)(data))),
|
||||
filenames: filenames,
|
||||
X: int(x),
|
||||
Y: int(y),
|
||||
// Window ID is stored as the pointer value itself (not pointing to memory)
|
||||
// Same pattern as other signal handlers in this file
|
||||
windowId := uint(uintptr(data))
|
||||
targetWindow, ok := globalApplication.Window.GetByID(windowId)
|
||||
if !ok || targetWindow == nil {
|
||||
globalApplication.error("onUriList could not find window with ID: %d", windowId)
|
||||
return
|
||||
}
|
||||
|
||||
// Send to frontend for drop target detection and filtering
|
||||
targetWindow.InitiateFrontendDropProcessing(filenames, int(x), int(y))
|
||||
}
|
||||
|
||||
var debounceTimer *time.Timer
|
||||
|
|
|
|||
|
|
@ -393,12 +393,15 @@ func appName() string {
|
|||
}
|
||||
|
||||
func appNew(name string) pointer {
|
||||
GApplicationDefaultFlags := uint(0)
|
||||
// Use NON_UNIQUE to allow multiple instances of the application to run
|
||||
// This matches the behavior of gtk_init/gtk_main used in v2
|
||||
// G_APPLICATION_NON_UNIQUE = (1 << 5) = 32
|
||||
GApplicationNonUnique := uint(32)
|
||||
|
||||
// Name is already sanitized by sanitizeAppName() in application_linux.go
|
||||
identifier := fmt.Sprintf("org.wails.%s", name)
|
||||
|
||||
return pointer(gtkApplicationNew(identifier, GApplicationDefaultFlags))
|
||||
return pointer(gtkApplicationNew(identifier, GApplicationNonUnique))
|
||||
}
|
||||
|
||||
func appRun(application pointer) error {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package application
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/errs"
|
||||
)
|
||||
|
|
@ -58,7 +57,7 @@ const (
|
|||
WindowZoomOut = 47
|
||||
WindowZoomReset = 48
|
||||
WindowSnapAssist = 49
|
||||
WindowDropZoneDropped = 50
|
||||
WindowFilesDropped = 50
|
||||
WindowPrint = 51
|
||||
)
|
||||
|
||||
|
|
@ -112,7 +111,7 @@ var windowMethodNames = map[int]string{
|
|||
WindowZoomIn: "ZoomIn",
|
||||
WindowZoomOut: "ZoomOut",
|
||||
WindowZoomReset: "ZoomReset",
|
||||
WindowDropZoneDropped: "DropZoneDropped",
|
||||
WindowFilesDropped: "FilesDropped",
|
||||
WindowSnapAssist: "SnapAssist",
|
||||
WindowPrint: "Print",
|
||||
}
|
||||
|
|
@ -354,18 +353,11 @@ func (m *MessageProcessor) processWindowMethod(
|
|||
case WindowZoomReset:
|
||||
window.ZoomReset()
|
||||
return unit, nil
|
||||
case WindowDropZoneDropped:
|
||||
m.Info(
|
||||
"[DragDropDebug] processWindowMethod: Entered WindowDropZoneDropped case",
|
||||
)
|
||||
|
||||
slog.Info("[DragDropDebug] Raw 'args' payload string:", "data", string(req.Args.rawData))
|
||||
|
||||
case WindowFilesDropped:
|
||||
var payload fileDropPayload
|
||||
|
||||
err := req.Args.ToStruct(&payload)
|
||||
if err != nil {
|
||||
return nil, errs.WrapInvalidWindowCallErrorf(err, "Error decoding file drop payload from 'args' parameter")
|
||||
return nil, errs.WrapInvalidWindowCallErrorf(err, "error decoding file drop payload")
|
||||
}
|
||||
m.Info(
|
||||
"[DragDropDebug] processWindowMethod: Decoded payload from 'args'",
|
||||
|
|
@ -373,30 +365,24 @@ func (m *MessageProcessor) processWindowMethod(
|
|||
fmt.Sprintf("%+v", payload),
|
||||
)
|
||||
|
||||
dropDetails := &DropZoneDetails{
|
||||
dropTarget := &DropTargetDetails{
|
||||
X: payload.X,
|
||||
Y: payload.Y,
|
||||
ElementID: payload.ElementDetails.ID,
|
||||
ClassList: payload.ElementDetails.ClassList,
|
||||
Attributes: payload.ElementDetails.Attributes, // Assumes DropZoneDetails struct is updated to include this field
|
||||
Attributes: payload.ElementDetails.Attributes,
|
||||
}
|
||||
|
||||
wvWindow, ok := window.(*WebviewWindow)
|
||||
if !ok {
|
||||
return nil, errs.NewInvalidWindowCallErrorf("Error: Target window is not a WebviewWindow for FilesDroppedWithContext")
|
||||
return nil, errs.NewInvalidWindowCallErrorf("target window is not a WebviewWindow")
|
||||
}
|
||||
|
||||
msg := &dragAndDropMessage{
|
||||
windowId: wvWindow.id,
|
||||
filenames: payload.Filenames,
|
||||
DropZone: dropDetails,
|
||||
windowId: wvWindow.id,
|
||||
filenames: payload.Filenames,
|
||||
DropTarget: dropTarget,
|
||||
}
|
||||
|
||||
m.Info(
|
||||
"[DragDropDebug] processApplicationMethod: Sending message to windowDragAndDropBuffer",
|
||||
"message",
|
||||
fmt.Sprintf("%+v", msg),
|
||||
)
|
||||
windowDragAndDropBuffer <- msg
|
||||
return unit, nil
|
||||
case WindowSnapAssist:
|
||||
|
|
|
|||
|
|
@ -1180,7 +1180,7 @@ func (w *WebviewWindow) SetFrameless(frameless bool) Window {
|
|||
}
|
||||
|
||||
func (w *WebviewWindow) DispatchWailsEvent(event *CustomEvent) {
|
||||
msg := fmt.Sprintf("_wails.dispatchWailsEvent(%s);", event.ToJSON())
|
||||
msg := fmt.Sprintf("window._wails.dispatchWailsEvent(%s);", event.ToJSON())
|
||||
w.ExecJS(msg)
|
||||
}
|
||||
|
||||
|
|
@ -1205,37 +1205,16 @@ func (w *WebviewWindow) Error(message string, args ...any) {
|
|||
globalApplication.error("in window '%s': "+message, args...)
|
||||
}
|
||||
|
||||
func (w *WebviewWindow) HandleDragAndDropMessage(filenames []string, dropZone *DropZoneDetails) {
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] HandleDragAndDropMessage called",
|
||||
"files", filenames,
|
||||
"dropZone", dropZone,
|
||||
)
|
||||
func (w *WebviewWindow) handleDragAndDropMessage(filenames []string, dropTarget *DropTargetDetails) {
|
||||
thisEvent := NewWindowEvent()
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] HandleDragAndDropMessage: thisEvent created",
|
||||
"ctx", thisEvent.ctx,
|
||||
)
|
||||
ctx := newWindowEventContext()
|
||||
ctx.setDroppedFiles(filenames)
|
||||
if dropZone != nil { // Check if dropZone details are available
|
||||
ctx.setDropZoneDetails(dropZone)
|
||||
if dropTarget != nil {
|
||||
ctx.setDropTargetDetails(dropTarget)
|
||||
}
|
||||
thisEvent.ctx = ctx
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] HandleDragAndDropMessage: thisEvent.ctx assigned",
|
||||
"thisEvent.ctx", thisEvent.ctx,
|
||||
"ctx", ctx,
|
||||
)
|
||||
listeners := w.eventListeners[uint(events.Common.WindowDropZoneFilesDropped)]
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] HandleDragAndDropMessage: Found listeners for WindowDropZoneFilesDropped",
|
||||
"count", len(listeners),
|
||||
)
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] HandleDragAndDropMessage: Before calling listeners",
|
||||
"thisEvent.ctx", thisEvent.ctx,
|
||||
)
|
||||
|
||||
listeners := w.eventListeners[uint(events.Common.WindowFilesDropped)]
|
||||
for _, listener := range listeners {
|
||||
if listener == nil {
|
||||
continue
|
||||
|
|
@ -1454,11 +1433,6 @@ func (w *WebviewWindow) ToggleMenuBar() {
|
|||
}
|
||||
|
||||
func (w *WebviewWindow) InitiateFrontendDropProcessing(filenames []string, x int, y int) {
|
||||
globalApplication.debug(
|
||||
"[DragDropDebug] InitiateFrontendDropProcessing called",
|
||||
"x", x,
|
||||
"y", y,
|
||||
)
|
||||
if w.impl == nil || w.isDestroyed() {
|
||||
return
|
||||
}
|
||||
|
|
@ -1470,7 +1444,7 @@ func (w *WebviewWindow) InitiateFrontendDropProcessing(filenames []string, x int
|
|||
}
|
||||
|
||||
jsCall := fmt.Sprintf(
|
||||
"window._wails.handlePlatformFileDrop(%s, %d, %d);",
|
||||
"window.wails.Window.HandlePlatformFileDrop(%s, %d, %d);",
|
||||
string(filenamesJSON),
|
||||
x,
|
||||
y,
|
||||
|
|
@ -1487,6 +1461,65 @@ func (w *WebviewWindow) InitiateFrontendDropProcessing(filenames []string, x int
|
|||
})
|
||||
}
|
||||
|
||||
// HandleDragEnter is called when drag enters the window (Linux only, since GTK intercepts drag events)
|
||||
func (w *WebviewWindow) HandleDragEnter() {
|
||||
if w.impl == nil || w.isDestroyed() || !w.runtimeLoaded {
|
||||
return
|
||||
}
|
||||
|
||||
// Reset drag hover state for new drag session
|
||||
dragHover.lastSentX = 0
|
||||
dragHover.lastSentY = 0
|
||||
|
||||
w.impl.execJS("window._wails.handleDragEnter();")
|
||||
}
|
||||
|
||||
// Drag hover throttle state
|
||||
var dragHover struct {
|
||||
lastSentX int
|
||||
lastSentY int
|
||||
}
|
||||
|
||||
// HandleDragOver is called during drag-motion to update hover state in JS
|
||||
// This is called from the GTK main thread, so we can call execJS directly
|
||||
func (w *WebviewWindow) HandleDragOver(x int, y int) {
|
||||
if w.impl == nil || w.isDestroyed() || !w.runtimeLoaded {
|
||||
return
|
||||
}
|
||||
|
||||
// Throttle: only send if moved at least 5 pixels
|
||||
dx := x - dragHover.lastSentX
|
||||
dy := y - dragHover.lastSentY
|
||||
if dx < 0 {
|
||||
dx = -dx
|
||||
}
|
||||
if dy < 0 {
|
||||
dy = -dy
|
||||
}
|
||||
if dx < 5 && dy < 5 {
|
||||
return
|
||||
}
|
||||
dragHover.lastSentX = x
|
||||
dragHover.lastSentY = y
|
||||
|
||||
// Use platform-specific zero-alloc implementation if available
|
||||
if impl, ok := w.impl.(interface{ execJSDragOver(x, y int) }); ok {
|
||||
impl.execJSDragOver(x, y)
|
||||
} else {
|
||||
w.impl.execJS(fmt.Sprintf("window._wails.handleDragOver(%d,%d)", x, y))
|
||||
}
|
||||
}
|
||||
|
||||
// HandleDragLeave is called when drag leaves the window
|
||||
func (w *WebviewWindow) HandleDragLeave() {
|
||||
if w.impl == nil || w.isDestroyed() || !w.runtimeLoaded {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't use InvokeSync - execJS already handles main thread dispatch internally
|
||||
w.impl.execJS("window._wails.handleDragLeave();")
|
||||
}
|
||||
|
||||
// SnapAssist triggers the Windows Snap Assist feature by simulating Win+Z key combination.
|
||||
// On Windows, this opens the snap layout options. On Linux and macOS, this is a no-op.
|
||||
func (w *WebviewWindow) SnapAssist() {
|
||||
|
|
|
|||
|
|
@ -352,6 +352,12 @@ void windowExecJS(void* nsWindow, const char* js) {
|
|||
free((void*)js);
|
||||
}
|
||||
|
||||
// Execute JS without allocation - buffer is NOT freed
|
||||
void windowExecJSNoAlloc(void* nsWindow, const char* js) {
|
||||
WebviewWindow* window = (WebviewWindow*)nsWindow;
|
||||
[window.webView evaluateJavaScript:[NSString stringWithUTF8String:js] completionHandler:nil];
|
||||
}
|
||||
|
||||
// Make NSWindow backdrop translucent
|
||||
void windowSetTranslucent(void* nsWindow) {
|
||||
// Get window
|
||||
|
|
@ -847,6 +853,7 @@ static void setContentProtection(void *nsWindow, bool enabled) {
|
|||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
|
|
@ -1094,6 +1101,17 @@ func (w *macosWebviewWindow) execJS(js string) {
|
|||
})
|
||||
}
|
||||
|
||||
// execJSDragOver executes JS for drag-over events with zero allocations
|
||||
// Must be called from main thread
|
||||
func (w *macosWebviewWindow) execJSDragOver(buffer []byte) {
|
||||
if w.nsWindow == nil {
|
||||
return
|
||||
}
|
||||
// Pass buffer directly to C without allocation
|
||||
// Buffer must be null-terminated
|
||||
C.windowExecJSNoAlloc(w.nsWindow, (*C.char)(unsafe.Pointer(&buffer[0])))
|
||||
}
|
||||
|
||||
func (w *macosWebviewWindow) setURL(uri string) {
|
||||
C.navigationLoadURL(w.nsWindow, C.CString(uri))
|
||||
}
|
||||
|
|
@ -1107,7 +1125,10 @@ func newWindowImpl(parent *WebviewWindow) *macosWebviewWindow {
|
|||
parent: parent,
|
||||
}
|
||||
result.parent.RegisterHook(events.Mac.WebViewDidFinishNavigation, func(event *WindowEvent) {
|
||||
result.execJS(runtime.Core(globalApplication.impl.GetFlags(globalApplication.options)))
|
||||
// Inject runtime core
|
||||
js := runtime.Core(globalApplication.impl.GetFlags(globalApplication.options))
|
||||
js += fmt.Sprintf("window._wails.flags.enableFileDrop=%v;", result.parent.options.EnableFileDrop)
|
||||
result.execJS(js)
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
|
@ -1241,7 +1262,7 @@ func (w *macosWebviewWindow) run() {
|
|||
C.int(options.Height),
|
||||
C.bool(macOptions.EnableFraudulentWebsiteWarnings),
|
||||
C.bool(options.Frameless),
|
||||
C.bool(options.EnableDragAndDrop),
|
||||
C.bool(options.EnableFileDrop),
|
||||
w.getWebviewPreferences(),
|
||||
)
|
||||
w.setTitle(options.Title)
|
||||
|
|
@ -1477,6 +1498,8 @@ func (w *macosWebviewWindow) setPhysicalBounds(physicalBounds Rect) {
|
|||
|
||||
func (w *macosWebviewWindow) destroy() {
|
||||
w.parent.markAsDestroyed()
|
||||
// Clear caches for this window
|
||||
clearWindowDragCache(w.parent.id)
|
||||
C.windowDestroy(w.nsWindow)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ typedef NS_ENUM(NSInteger, MacLiquidGlassStyle) {
|
|||
[super setDelegate: delegate];
|
||||
// If the delegate is our WebviewWindowDelegate (which handles NSDraggingDestination)
|
||||
if ([delegate isKindOfClass:[WebviewWindowDelegate class]]) {
|
||||
NSLog(@"WebviewWindow: setDelegate - Registering window for dragged types (NSFilenamesPboardType) because WebviewWindowDelegate is being set.");
|
||||
[self registerForDraggedTypes:@[NSFilenamesPboardType]]; // 'self' is the WebviewWindow instance
|
||||
}
|
||||
}
|
||||
|
|
@ -246,53 +245,40 @@ typedef NS_ENUM(NSInteger, MacLiquidGlassStyle) {
|
|||
@end
|
||||
@implementation WebviewWindowDelegate
|
||||
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewWindowDelegate: draggingEntered called. WindowID: %u", self.windowId);
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
if ([[pasteboard types] containsObject:NSFilenamesPboardType]) {
|
||||
NSLog(@"WebviewWindowDelegate: draggingEntered - Found NSFilenamesPboardType. Firing EventWindowFileDraggingEntered.");
|
||||
// We need to ensure processWindowEvent is available or adapt this part
|
||||
// For now, let's assume it's available globally or via an import
|
||||
if (hasListeners(EventWindowFileDraggingEntered)) {
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingEntered);
|
||||
}
|
||||
return NSDragOperationCopy;
|
||||
}
|
||||
NSLog(@"WebviewWindowDelegate: draggingEntered - NSFilenamesPboardType NOT found.");
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
- (void)draggingExited:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewWindowDelegate: draggingExited called. WindowID: %u", self.windowId);
|
||||
if (hasListeners(EventWindowFileDraggingExited)) {
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingExited);
|
||||
}
|
||||
}
|
||||
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewWindowDelegate: prepareForDragOperation called. WindowID: %u", self.windowId);
|
||||
return YES;
|
||||
}
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation called. WindowID: %u", self.windowId);
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
if (hasListeners(EventWindowFileDraggingPerformed)) {
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingPerformed);
|
||||
}
|
||||
if ([[pasteboard types] containsObject:NSFilenamesPboardType]) {
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - Found NSFilenamesPboardType.");
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
NSUInteger count = [files count];
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - File count: %lu", (unsigned long)count);
|
||||
if (count == 0) {
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - No files found in pasteboard, though type was present.");
|
||||
return NO;
|
||||
}
|
||||
char** cArray = (char**)malloc(count * sizeof(char*));
|
||||
if (cArray == NULL) {
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - Failed to allocate memory for file array.");
|
||||
return NO;
|
||||
}
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
NSString* str = files[i];
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - File %lu: %@", (unsigned long)i, str);
|
||||
cArray[i] = (char*)[str UTF8String];
|
||||
}
|
||||
// Get the WebviewWindow instance, which is the dragging destination
|
||||
|
|
@ -303,14 +289,10 @@ typedef NS_ENUM(NSInteger, MacLiquidGlassStyle) {
|
|||
CGFloat viewHeight = webView.frame.size.height;
|
||||
int x = (int)dropPointInView.x;
|
||||
int y = (int)(viewHeight - dropPointInView.y); // Flip Y for web coordinate system
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - Coords: x=%d, y=%d. ViewHeight: %f", x, y, viewHeight);
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - Calling processDragItems for windowId %u.", self.windowId);
|
||||
processDragItems(self.windowId, cArray, (int)count, x, y); // self.windowId is from the delegate
|
||||
free(cArray);
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - Returned from processDragItems.");
|
||||
return NO;
|
||||
}
|
||||
NSLog(@"WebviewWindowDelegate: performDragOperation - NSFilenamesPboardType NOT found. Returning NO.");
|
||||
return NO;
|
||||
}
|
||||
// Original WebviewWindowDelegate methods continue here...
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
#import "../events/events_darwin.h"
|
||||
|
||||
extern void processDragItems(unsigned int windowId, char** arr, int length, int x, int y);
|
||||
extern void macosOnDragEnter(unsigned int windowId);
|
||||
extern void macosOnDragExit(unsigned int windowId);
|
||||
extern void macosOnDragOver(unsigned int windowId, int x, int y);
|
||||
|
||||
@implementation WebviewDrag
|
||||
|
||||
|
|
@ -14,7 +17,6 @@ extern void processDragItems(unsigned int windowId, char** arr, int length, int
|
|||
- (instancetype)initWithFrame:(NSRect)frameRect {
|
||||
self = [super initWithFrame:frameRect];
|
||||
if (self) {
|
||||
NSLog(@"WebviewDrag: initWithFrame - Registering for dragged types. WindowID (at init if available, might be set later): %u", self.windowId); // self.windowId might not be set here yet.
|
||||
[self registerForDraggedTypes:@[NSFilenamesPboardType]];
|
||||
}
|
||||
return self;
|
||||
|
|
@ -22,47 +24,65 @@ extern void processDragItems(unsigned int windowId, char** arr, int length, int
|
|||
|
||||
// draggingEntered:
|
||||
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewDrag: draggingEntered called. WindowID: %u", self.windowId);
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
if ([[pasteboard types] containsObject:NSFilenamesPboardType]) {
|
||||
NSLog(@"WebviewDrag: draggingEntered - Found NSFilenamesPboardType. Firing EventWindowFileDraggingEntered.");
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingEntered);
|
||||
// Notify JS for hover effects
|
||||
macosOnDragEnter(self.windowId);
|
||||
return NSDragOperationCopy;
|
||||
}
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
// draggingUpdated:
|
||||
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
if ([[pasteboard types] containsObject:NSFilenamesPboardType]) {
|
||||
// Get the current mouse position
|
||||
NSPoint dropPointInWindow = [sender draggingLocation];
|
||||
NSPoint dropPointInView = [self convertPoint:dropPointInWindow fromView:nil];
|
||||
|
||||
// Get the window's content view height for coordinate conversion
|
||||
NSView *contentView = [self.window contentView];
|
||||
CGFloat contentHeight = contentView.frame.size.height;
|
||||
|
||||
int x = (int)dropPointInView.x;
|
||||
int y = (int)(contentHeight - dropPointInView.y);
|
||||
|
||||
// Notify JS for hover effects
|
||||
macosOnDragOver(self.windowId, x, y);
|
||||
|
||||
return NSDragOperationCopy;
|
||||
}
|
||||
NSLog(@"WebviewDrag: draggingEntered - NSFilenamesPboardType NOT found.");
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
// draggingExited:
|
||||
- (void)draggingExited:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewDrag: draggingExited called. WindowID: %u", self.windowId); // Added log
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingExited);
|
||||
// Notify JS to clean up hover effects
|
||||
macosOnDragExit(self.windowId);
|
||||
}
|
||||
|
||||
// prepareForDragOperation:
|
||||
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewDrag: prepareForDragOperation called. WindowID: %u", self.windowId); // Added log
|
||||
return YES;
|
||||
}
|
||||
|
||||
// performDragOperation:
|
||||
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
|
||||
NSLog(@"WebviewDrag: performDragOperation called. WindowID: %u", self.windowId);
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
processWindowEvent(self.windowId, EventWindowFileDraggingPerformed);
|
||||
if ([[pasteboard types] containsObject:NSFilenamesPboardType]) {
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
NSUInteger count = [files count];
|
||||
NSLog(@"WebviewDrag: performDragOperation - File count: %lu", (unsigned long)count);
|
||||
if (count == 0) {
|
||||
NSLog(@"WebviewDrag: performDragOperation - No files found in pasteboard, though type was present.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
char** cArray = (char**)malloc(count * sizeof(char*));
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
NSString* str = files[i];
|
||||
NSLog(@"WebviewDrag: performDragOperation - File %lu: %@", (unsigned long)i, str);
|
||||
cArray[i] = (char*)[str UTF8String];
|
||||
}
|
||||
|
||||
|
|
@ -73,18 +93,14 @@ extern void processDragItems(unsigned int windowId, char** arr, int length, int
|
|||
NSView *contentView = [self.window contentView];
|
||||
CGFloat contentHeight = contentView.frame.size.height;
|
||||
|
||||
NSLog(@"WebviewDrag: Self height: %.2f, Content view height: %.2f", self.frame.size.height, contentHeight);
|
||||
|
||||
int x = (int)dropPointInView.x;
|
||||
// Use the content view height for conversion
|
||||
int y = (int)(contentHeight - dropPointInView.y);
|
||||
|
||||
processDragItems(self.windowId, cArray, (int)count, x, y);
|
||||
free(cArray);
|
||||
NSLog(@"WebviewDrag: performDragOperation - Returned from processDragItems.");
|
||||
return YES;
|
||||
}
|
||||
NSLog(@"WebviewDrag: performDragOperation - NSFilenamesPboardType NOT found. Returning NO.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,8 +282,10 @@ func (w *linuxWebviewWindow) run() {
|
|||
w.window, w.webview, w.vbox = windowNew(app.application, w.gtkmenu, w.parent.id, w.parent.options.Linux.WebviewGpuPolicy)
|
||||
app.registerWindow(w.window, w.parent.id) // record our mapping
|
||||
w.connectSignals()
|
||||
if w.parent.options.EnableDragAndDrop {
|
||||
if w.parent.options.EnableFileDrop {
|
||||
w.enableDND()
|
||||
} else {
|
||||
w.disableDND()
|
||||
}
|
||||
w.setTitle(w.parent.options.Title)
|
||||
w.setIcon(app.icon)
|
||||
|
|
@ -352,7 +354,10 @@ func (w *linuxWebviewWindow) run() {
|
|||
})
|
||||
|
||||
w.parent.RegisterHook(events.Linux.WindowLoadFinished, func(e *WindowEvent) {
|
||||
w.execJS(runtime.Core(globalApplication.impl.GetFlags(globalApplication.options)))
|
||||
// Inject runtime core and EnableFileDrop flag together
|
||||
js := runtime.Core(globalApplication.impl.GetFlags(globalApplication.options))
|
||||
js += fmt.Sprintf("window._wails.flags.enableFileDrop=%v;", w.parent.options.EnableFileDrop)
|
||||
w.execJS(js)
|
||||
})
|
||||
if w.parent.options.HTML != "" {
|
||||
w.setHTML(w.parent.options.HTML)
|
||||
|
|
|
|||
|
|
@ -104,8 +104,10 @@ type WebviewWindowOptions struct {
|
|||
// ZoomControlEnabled will enable the zoom control.
|
||||
ZoomControlEnabled bool
|
||||
|
||||
// EnableDragAndDrop will enable drag and drop.
|
||||
EnableDragAndDrop bool
|
||||
// EnableFileDrop enables drag and drop of files onto the window.
|
||||
// When enabled, files dragged from the OS onto elements with the
|
||||
// `data-file-drop-target` attribute will trigger a FilesDropped event.
|
||||
EnableFileDrop bool
|
||||
|
||||
// OpenInspectorOnStartup will open the inspector when the window is first shown.
|
||||
OpenInspectorOnStartup bool
|
||||
|
|
@ -182,20 +184,6 @@ const (
|
|||
/******* Windows Options *******/
|
||||
|
||||
type BackdropType int32
|
||||
type DragEffect int32
|
||||
|
||||
const (
|
||||
// DragEffectNone is used to indicate that the drop target cannot accept the data.
|
||||
DragEffectNone DragEffect = 1
|
||||
// DragEffectCopy is used to indicate that the data is copied to the drop target.
|
||||
DragEffectCopy DragEffect = 2
|
||||
// DragEffectMove is used to indicate that the data is removed from the drag source.
|
||||
DragEffectMove DragEffect = 3
|
||||
// DragEffectLink is used to indicate that a link to the original data is established.
|
||||
DragEffectLink DragEffect = 4
|
||||
// DragEffectScroll is used to indicate that the target can be scrolled while dragging to locate a drop position that is not currently visible in the target.
|
||||
|
||||
)
|
||||
|
||||
const (
|
||||
Auto BackdropType = 0
|
||||
|
|
@ -281,10 +269,6 @@ type WindowsWindow struct {
|
|||
// Menu is the menu to use for the window.
|
||||
Menu *Menu
|
||||
|
||||
// Drag Cursor Effects
|
||||
OnEnterEffect DragEffect
|
||||
OnOverEffect DragEffect
|
||||
|
||||
// Permissions map for WebView2. If empty, default permissions will be granted.
|
||||
Permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState
|
||||
|
||||
|
|
|
|||
|
|
@ -82,21 +82,6 @@ func TestBackdropType_Constants(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDragEffect_Constants(t *testing.T) {
|
||||
if DragEffectNone != 1 {
|
||||
t.Error("DragEffectNone should be 1")
|
||||
}
|
||||
if DragEffectCopy != 2 {
|
||||
t.Error("DragEffectCopy should be 2")
|
||||
}
|
||||
if DragEffectMove != 3 {
|
||||
t.Error("DragEffectMove should be 3")
|
||||
}
|
||||
if DragEffectLink != 4 {
|
||||
t.Error("DragEffectLink should be 4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheme_Constants(t *testing.T) {
|
||||
if SystemDefault != 0 {
|
||||
t.Error("SystemDefault should be 0")
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
|
|
@ -67,7 +66,6 @@ type windowsWebviewWindow struct {
|
|||
resizeBorderWidth int32
|
||||
resizeBorderHeight int32
|
||||
focusingChromium bool
|
||||
dropTarget *w32.DropTarget
|
||||
onceDo sync.Once
|
||||
|
||||
// Window move debouncer
|
||||
|
|
@ -721,9 +719,6 @@ func (w *windowsWebviewWindow) setRelativePosition(x int, y int) {
|
|||
|
||||
func (w *windowsWebviewWindow) destroy() {
|
||||
w.parent.markAsDestroyed()
|
||||
if w.dropTarget != nil {
|
||||
w.dropTarget.Release()
|
||||
}
|
||||
// destroy the window
|
||||
w32.DestroyWindow(w.hwnd)
|
||||
}
|
||||
|
|
@ -1977,66 +1972,20 @@ func (w *windowsWebviewWindow) setupChromium() {
|
|||
}
|
||||
}
|
||||
|
||||
if w.parent.options.EnableDragAndDrop {
|
||||
if chromium.HasCapability(edge.AllowExternalDrop) {
|
||||
err := chromium.AllowExternalDrag(false)
|
||||
if err != nil {
|
||||
globalApplication.handleFatalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize OLE for drag-and-drop operations
|
||||
w32.OleInitialise()
|
||||
|
||||
w.dropTarget = w32.NewDropTarget()
|
||||
w.dropTarget.OnDrop = func(files []string, x int, y int) {
|
||||
w.parent.emit(events.Windows.WindowDragDrop)
|
||||
globalApplication.debug("[DragDropDebug] Windows DropTarget OnDrop: Raw screen coordinates", "x", x, "y", y)
|
||||
|
||||
// Convert screen coordinates to window-relative coordinates first
|
||||
// Windows DropTarget gives us screen coordinates, but we need window-relative coordinates
|
||||
windowRect := w32.GetWindowRect(w.hwnd)
|
||||
windowRelativeX := x - int(windowRect.Left)
|
||||
windowRelativeY := y - int(windowRect.Top)
|
||||
|
||||
globalApplication.debug("[DragDropDebug] Windows DropTarget OnDrop: After screen-to-window conversion", "windowRelativeX", windowRelativeX, "windowRelativeY", windowRelativeY)
|
||||
|
||||
// Convert window-relative coordinates to webview-relative coordinates
|
||||
webviewX, webviewY := w.convertWindowToWebviewCoordinates(windowRelativeX, windowRelativeY)
|
||||
globalApplication.debug("[DragDropDebug] Windows DropTarget OnDrop: Final webview coordinates", "webviewX", webviewX, "webviewY", webviewY)
|
||||
w.parent.InitiateFrontendDropProcessing(files, webviewX, webviewY)
|
||||
}
|
||||
if opts.OnEnterEffect != 0 {
|
||||
w.dropTarget.OnEnterEffect = convertEffect(opts.OnEnterEffect)
|
||||
}
|
||||
if opts.OnOverEffect != 0 {
|
||||
w.dropTarget.OnOverEffect = convertEffect(opts.OnOverEffect)
|
||||
}
|
||||
w.dropTarget.OnEnter = func() {
|
||||
w.parent.emit(events.Windows.WindowDragEnter)
|
||||
}
|
||||
w.dropTarget.OnLeave = func() {
|
||||
w.parent.emit(events.Windows.WindowDragLeave)
|
||||
}
|
||||
w.dropTarget.OnOver = func() {
|
||||
w.parent.emit(events.Windows.WindowDragOver)
|
||||
}
|
||||
// Enumerate all the child windows for this window and register them as drop targets
|
||||
w32.EnumChildWindows(w.hwnd, func(hwnd w32.HWND, lparam w32.LPARAM) w32.LRESULT {
|
||||
// Check if the window class is "Chrome_RenderWidgetHostHWND"
|
||||
// If it is, then we register it as a drop target
|
||||
//windowName := w32.GetClassName(hwnd)
|
||||
//println(windowName)
|
||||
//if windowName == "Chrome_RenderWidgetHostHWND" {
|
||||
err := w32.RegisterDragDrop(hwnd, w.dropTarget)
|
||||
if err != nil && !errors.Is(err, syscall.Errno(w32.DRAGDROP_E_ALREADYREGISTERED)) {
|
||||
globalApplication.error("error registering drag and drop: %w", err)
|
||||
}
|
||||
//}
|
||||
return 1
|
||||
})
|
||||
|
||||
}
|
||||
// File drop handling on Windows:
|
||||
// WebView2's AllowExternalDrop controls ALL drag-and-drop (both external file drops
|
||||
// AND internal HTML5 drag-and-drop). We cannot disable it without breaking HTML5 DnD.
|
||||
//
|
||||
// When EnableFileDrop is true:
|
||||
// - JS dragenter/dragover/drop events fire for external file drags
|
||||
// - JS calls preventDefault() to stop the browser from navigating to the file
|
||||
// - JS uses chrome.webview.postMessageWithAdditionalObjects to send file paths to Go
|
||||
// - Go receives paths via processMessageWithAdditionalObjects
|
||||
//
|
||||
// When EnableFileDrop is false:
|
||||
// - We cannot use AllowExternalDrag(false) as it breaks HTML5 internal drag-and-drop
|
||||
// - JS runtime checks window._wails.flags.enableFileDrop and shows "no drop" cursor
|
||||
// - The enableFileDrop flag is injected in navigationCompleted callback
|
||||
|
||||
err = chromium.PutIsGeneralAutofillEnabled(opts.GeneralAutofillEnabled)
|
||||
if err != nil {
|
||||
|
|
@ -2151,19 +2100,6 @@ func (w *windowsWebviewWindow) fullscreenChanged(
|
|||
}
|
||||
}
|
||||
|
||||
func convertEffect(effect DragEffect) w32.DWORD {
|
||||
switch effect {
|
||||
case DragEffectCopy:
|
||||
return w32.DROPEFFECT_COPY
|
||||
case DragEffectMove:
|
||||
return w32.DROPEFFECT_MOVE
|
||||
case DragEffectLink:
|
||||
return w32.DROPEFFECT_LINK
|
||||
default:
|
||||
return w32.DROPEFFECT_NONE
|
||||
}
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) flash(enabled bool) {
|
||||
w32.FlashWindow(w.hwnd, enabled)
|
||||
}
|
||||
|
|
@ -2176,6 +2112,10 @@ func (w *windowsWebviewWindow) navigationCompleted(
|
|||
// Install the runtime core
|
||||
w.execJS(runtime.Core(globalApplication.impl.GetFlags(globalApplication.options)))
|
||||
|
||||
// Set the EnableFileDrop flag for this window (Windows-specific)
|
||||
// The JS runtime checks this before processing file drops
|
||||
w.execJS(fmt.Sprintf("window._wails.flags.enableFileDrop = %v;", w.parent.options.EnableFileDrop))
|
||||
|
||||
// EmitEvent DomReady ApplicationEvent
|
||||
windowEvents <- &windowEvent{EventID: uint(events.Windows.WebViewNavigationCompleted), WindowID: w.parent.id}
|
||||
|
||||
|
|
@ -2277,7 +2217,7 @@ func (w *windowsWebviewWindow) processMessageWithAdditionalObjects(
|
|||
sender *edge.ICoreWebView2,
|
||||
args *edge.ICoreWebView2WebMessageReceivedEventArgs,
|
||||
) {
|
||||
if strings.HasPrefix(message, "FilesDropped") {
|
||||
if strings.HasPrefix(message, "file:drop:") {
|
||||
objs, err := args.GetAdditionalObjects()
|
||||
if err != nil {
|
||||
globalApplication.handleError(err)
|
||||
|
|
@ -2319,14 +2259,14 @@ func (w *windowsWebviewWindow) processMessageWithAdditionalObjects(
|
|||
filenames = append(filenames, filepath)
|
||||
}
|
||||
|
||||
// Extract X/Y coordinates from message - format should be "FilesDropped:x:y"
|
||||
// Extract X/Y coordinates from message - format is "file:drop:x:y"
|
||||
var x, y int
|
||||
parts := strings.Split(message, ":")
|
||||
if len(parts) >= 3 {
|
||||
if parsedX, err := strconv.Atoi(parts[1]); err == nil {
|
||||
if len(parts) >= 4 {
|
||||
if parsedX, err := strconv.Atoi(parts[2]); err == nil {
|
||||
x = parsedX
|
||||
}
|
||||
if parsedY, err := strconv.Atoi(parts[2]); err == nil {
|
||||
if parsedY, err := strconv.Atoi(parts[3]); err == nil {
|
||||
y = parsedY
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ type Window interface {
|
|||
GetBorderSizes() *LRTB
|
||||
GetScreen() (*Screen, error)
|
||||
GetZoom() float64
|
||||
HandleDragAndDropMessage(filenames []string, dropZone *DropZoneDetails)
|
||||
handleDragAndDropMessage(filenames []string, dropTarget *DropTargetDetails)
|
||||
InitiateFrontendDropProcessing(filenames []string, x int, y int)
|
||||
HandleMessage(message string)
|
||||
HandleWindowEvent(id uint)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ type commonEvents struct {
|
|||
WindowZoomIn WindowEventType
|
||||
WindowZoomOut WindowEventType
|
||||
WindowZoomReset WindowEventType
|
||||
WindowDropZoneFilesDropped WindowEventType
|
||||
}
|
||||
|
||||
func newCommonEvents() commonEvents {
|
||||
|
|
@ -63,7 +62,6 @@ func newCommonEvents() commonEvents {
|
|||
WindowZoomIn: 1047,
|
||||
WindowZoomOut: 1048,
|
||||
WindowZoomReset: 1049,
|
||||
WindowDropZoneFilesDropped: 1050,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,17 +83,17 @@ type linuxEvents struct {
|
|||
|
||||
func newLinuxEvents() linuxEvents {
|
||||
return linuxEvents{
|
||||
ApplicationStartup: 1051,
|
||||
SystemThemeChanged: 1052,
|
||||
WindowDeleteEvent: 1053,
|
||||
WindowDidMove: 1054,
|
||||
WindowDidResize: 1055,
|
||||
WindowFocusIn: 1056,
|
||||
WindowFocusOut: 1057,
|
||||
WindowLoadStarted: 1058,
|
||||
WindowLoadRedirected: 1059,
|
||||
WindowLoadCommitted: 1060,
|
||||
WindowLoadFinished: 1061,
|
||||
ApplicationStartup: 1050,
|
||||
SystemThemeChanged: 1051,
|
||||
WindowDeleteEvent: 1052,
|
||||
WindowDidMove: 1053,
|
||||
WindowDidResize: 1054,
|
||||
WindowFocusIn: 1055,
|
||||
WindowFocusOut: 1056,
|
||||
WindowLoadStarted: 1057,
|
||||
WindowLoadRedirected: 1058,
|
||||
WindowLoadCommitted: 1059,
|
||||
WindowLoadFinished: 1060,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,138 +236,138 @@ type macEvents struct {
|
|||
|
||||
func newMacEvents() macEvents {
|
||||
return macEvents{
|
||||
ApplicationDidBecomeActive: 1062,
|
||||
ApplicationDidChangeBackingProperties: 1063,
|
||||
ApplicationDidChangeEffectiveAppearance: 1064,
|
||||
ApplicationDidChangeIcon: 1065,
|
||||
ApplicationDidChangeOcclusionState: 1066,
|
||||
ApplicationDidChangeScreenParameters: 1067,
|
||||
ApplicationDidChangeStatusBarFrame: 1068,
|
||||
ApplicationDidChangeStatusBarOrientation: 1069,
|
||||
ApplicationDidChangeTheme: 1070,
|
||||
ApplicationDidFinishLaunching: 1071,
|
||||
ApplicationDidHide: 1072,
|
||||
ApplicationDidResignActive: 1073,
|
||||
ApplicationDidUnhide: 1074,
|
||||
ApplicationDidUpdate: 1075,
|
||||
ApplicationShouldHandleReopen: 1076,
|
||||
ApplicationWillBecomeActive: 1077,
|
||||
ApplicationWillFinishLaunching: 1078,
|
||||
ApplicationWillHide: 1079,
|
||||
ApplicationWillResignActive: 1080,
|
||||
ApplicationWillTerminate: 1081,
|
||||
ApplicationWillUnhide: 1082,
|
||||
ApplicationWillUpdate: 1083,
|
||||
MenuDidAddItem: 1084,
|
||||
MenuDidBeginTracking: 1085,
|
||||
MenuDidClose: 1086,
|
||||
MenuDidDisplayItem: 1087,
|
||||
MenuDidEndTracking: 1088,
|
||||
MenuDidHighlightItem: 1089,
|
||||
MenuDidOpen: 1090,
|
||||
MenuDidPopUp: 1091,
|
||||
MenuDidRemoveItem: 1092,
|
||||
MenuDidSendAction: 1093,
|
||||
MenuDidSendActionToItem: 1094,
|
||||
MenuDidUpdate: 1095,
|
||||
MenuWillAddItem: 1096,
|
||||
MenuWillBeginTracking: 1097,
|
||||
MenuWillDisplayItem: 1098,
|
||||
MenuWillEndTracking: 1099,
|
||||
MenuWillHighlightItem: 1100,
|
||||
MenuWillOpen: 1101,
|
||||
MenuWillPopUp: 1102,
|
||||
MenuWillRemoveItem: 1103,
|
||||
MenuWillSendAction: 1104,
|
||||
MenuWillSendActionToItem: 1105,
|
||||
MenuWillUpdate: 1106,
|
||||
WebViewDidCommitNavigation: 1107,
|
||||
WebViewDidFinishNavigation: 1108,
|
||||
WebViewDidReceiveServerRedirectForProvisionalNavigation: 1109,
|
||||
WebViewDidStartProvisionalNavigation: 1110,
|
||||
WindowDidBecomeKey: 1111,
|
||||
WindowDidBecomeMain: 1112,
|
||||
WindowDidBeginSheet: 1113,
|
||||
WindowDidChangeAlpha: 1114,
|
||||
WindowDidChangeBackingLocation: 1115,
|
||||
WindowDidChangeBackingProperties: 1116,
|
||||
WindowDidChangeCollectionBehavior: 1117,
|
||||
WindowDidChangeEffectiveAppearance: 1118,
|
||||
WindowDidChangeOcclusionState: 1119,
|
||||
WindowDidChangeOrderingMode: 1120,
|
||||
WindowDidChangeScreen: 1121,
|
||||
WindowDidChangeScreenParameters: 1122,
|
||||
WindowDidChangeScreenProfile: 1123,
|
||||
WindowDidChangeScreenSpace: 1124,
|
||||
WindowDidChangeScreenSpaceProperties: 1125,
|
||||
WindowDidChangeSharingType: 1126,
|
||||
WindowDidChangeSpace: 1127,
|
||||
WindowDidChangeSpaceOrderingMode: 1128,
|
||||
WindowDidChangeTitle: 1129,
|
||||
WindowDidChangeToolbar: 1130,
|
||||
WindowDidDeminiaturize: 1131,
|
||||
WindowDidEndSheet: 1132,
|
||||
WindowDidEnterFullScreen: 1133,
|
||||
WindowDidEnterVersionBrowser: 1134,
|
||||
WindowDidExitFullScreen: 1135,
|
||||
WindowDidExitVersionBrowser: 1136,
|
||||
WindowDidExpose: 1137,
|
||||
WindowDidFocus: 1138,
|
||||
WindowDidMiniaturize: 1139,
|
||||
WindowDidMove: 1140,
|
||||
WindowDidOrderOffScreen: 1141,
|
||||
WindowDidOrderOnScreen: 1142,
|
||||
WindowDidResignKey: 1143,
|
||||
WindowDidResignMain: 1144,
|
||||
WindowDidResize: 1145,
|
||||
WindowDidUpdate: 1146,
|
||||
WindowDidUpdateAlpha: 1147,
|
||||
WindowDidUpdateCollectionBehavior: 1148,
|
||||
WindowDidUpdateCollectionProperties: 1149,
|
||||
WindowDidUpdateShadow: 1150,
|
||||
WindowDidUpdateTitle: 1151,
|
||||
WindowDidUpdateToolbar: 1152,
|
||||
WindowDidZoom: 1153,
|
||||
WindowFileDraggingEntered: 1154,
|
||||
WindowFileDraggingExited: 1155,
|
||||
WindowFileDraggingPerformed: 1156,
|
||||
WindowHide: 1157,
|
||||
WindowMaximise: 1158,
|
||||
WindowUnMaximise: 1159,
|
||||
WindowMinimise: 1160,
|
||||
WindowUnMinimise: 1161,
|
||||
WindowShouldClose: 1162,
|
||||
WindowShow: 1163,
|
||||
WindowWillBecomeKey: 1164,
|
||||
WindowWillBecomeMain: 1165,
|
||||
WindowWillBeginSheet: 1166,
|
||||
WindowWillChangeOrderingMode: 1167,
|
||||
WindowWillClose: 1168,
|
||||
WindowWillDeminiaturize: 1169,
|
||||
WindowWillEnterFullScreen: 1170,
|
||||
WindowWillEnterVersionBrowser: 1171,
|
||||
WindowWillExitFullScreen: 1172,
|
||||
WindowWillExitVersionBrowser: 1173,
|
||||
WindowWillFocus: 1174,
|
||||
WindowWillMiniaturize: 1175,
|
||||
WindowWillMove: 1176,
|
||||
WindowWillOrderOffScreen: 1177,
|
||||
WindowWillOrderOnScreen: 1178,
|
||||
WindowWillResignMain: 1179,
|
||||
WindowWillResize: 1180,
|
||||
WindowWillUnfocus: 1181,
|
||||
WindowWillUpdate: 1182,
|
||||
WindowWillUpdateAlpha: 1183,
|
||||
WindowWillUpdateCollectionBehavior: 1184,
|
||||
WindowWillUpdateCollectionProperties: 1185,
|
||||
WindowWillUpdateShadow: 1186,
|
||||
WindowWillUpdateTitle: 1187,
|
||||
WindowWillUpdateToolbar: 1188,
|
||||
WindowWillUpdateVisibility: 1189,
|
||||
WindowWillUseStandardFrame: 1190,
|
||||
WindowZoomIn: 1191,
|
||||
WindowZoomOut: 1192,
|
||||
WindowZoomReset: 1193,
|
||||
ApplicationDidBecomeActive: 1061,
|
||||
ApplicationDidChangeBackingProperties: 1062,
|
||||
ApplicationDidChangeEffectiveAppearance: 1063,
|
||||
ApplicationDidChangeIcon: 1064,
|
||||
ApplicationDidChangeOcclusionState: 1065,
|
||||
ApplicationDidChangeScreenParameters: 1066,
|
||||
ApplicationDidChangeStatusBarFrame: 1067,
|
||||
ApplicationDidChangeStatusBarOrientation: 1068,
|
||||
ApplicationDidChangeTheme: 1069,
|
||||
ApplicationDidFinishLaunching: 1070,
|
||||
ApplicationDidHide: 1071,
|
||||
ApplicationDidResignActive: 1072,
|
||||
ApplicationDidUnhide: 1073,
|
||||
ApplicationDidUpdate: 1074,
|
||||
ApplicationShouldHandleReopen: 1075,
|
||||
ApplicationWillBecomeActive: 1076,
|
||||
ApplicationWillFinishLaunching: 1077,
|
||||
ApplicationWillHide: 1078,
|
||||
ApplicationWillResignActive: 1079,
|
||||
ApplicationWillTerminate: 1080,
|
||||
ApplicationWillUnhide: 1081,
|
||||
ApplicationWillUpdate: 1082,
|
||||
MenuDidAddItem: 1083,
|
||||
MenuDidBeginTracking: 1084,
|
||||
MenuDidClose: 1085,
|
||||
MenuDidDisplayItem: 1086,
|
||||
MenuDidEndTracking: 1087,
|
||||
MenuDidHighlightItem: 1088,
|
||||
MenuDidOpen: 1089,
|
||||
MenuDidPopUp: 1090,
|
||||
MenuDidRemoveItem: 1091,
|
||||
MenuDidSendAction: 1092,
|
||||
MenuDidSendActionToItem: 1093,
|
||||
MenuDidUpdate: 1094,
|
||||
MenuWillAddItem: 1095,
|
||||
MenuWillBeginTracking: 1096,
|
||||
MenuWillDisplayItem: 1097,
|
||||
MenuWillEndTracking: 1098,
|
||||
MenuWillHighlightItem: 1099,
|
||||
MenuWillOpen: 1100,
|
||||
MenuWillPopUp: 1101,
|
||||
MenuWillRemoveItem: 1102,
|
||||
MenuWillSendAction: 1103,
|
||||
MenuWillSendActionToItem: 1104,
|
||||
MenuWillUpdate: 1105,
|
||||
WebViewDidCommitNavigation: 1106,
|
||||
WebViewDidFinishNavigation: 1107,
|
||||
WebViewDidReceiveServerRedirectForProvisionalNavigation: 1108,
|
||||
WebViewDidStartProvisionalNavigation: 1109,
|
||||
WindowDidBecomeKey: 1110,
|
||||
WindowDidBecomeMain: 1111,
|
||||
WindowDidBeginSheet: 1112,
|
||||
WindowDidChangeAlpha: 1113,
|
||||
WindowDidChangeBackingLocation: 1114,
|
||||
WindowDidChangeBackingProperties: 1115,
|
||||
WindowDidChangeCollectionBehavior: 1116,
|
||||
WindowDidChangeEffectiveAppearance: 1117,
|
||||
WindowDidChangeOcclusionState: 1118,
|
||||
WindowDidChangeOrderingMode: 1119,
|
||||
WindowDidChangeScreen: 1120,
|
||||
WindowDidChangeScreenParameters: 1121,
|
||||
WindowDidChangeScreenProfile: 1122,
|
||||
WindowDidChangeScreenSpace: 1123,
|
||||
WindowDidChangeScreenSpaceProperties: 1124,
|
||||
WindowDidChangeSharingType: 1125,
|
||||
WindowDidChangeSpace: 1126,
|
||||
WindowDidChangeSpaceOrderingMode: 1127,
|
||||
WindowDidChangeTitle: 1128,
|
||||
WindowDidChangeToolbar: 1129,
|
||||
WindowDidDeminiaturize: 1130,
|
||||
WindowDidEndSheet: 1131,
|
||||
WindowDidEnterFullScreen: 1132,
|
||||
WindowDidEnterVersionBrowser: 1133,
|
||||
WindowDidExitFullScreen: 1134,
|
||||
WindowDidExitVersionBrowser: 1135,
|
||||
WindowDidExpose: 1136,
|
||||
WindowDidFocus: 1137,
|
||||
WindowDidMiniaturize: 1138,
|
||||
WindowDidMove: 1139,
|
||||
WindowDidOrderOffScreen: 1140,
|
||||
WindowDidOrderOnScreen: 1141,
|
||||
WindowDidResignKey: 1142,
|
||||
WindowDidResignMain: 1143,
|
||||
WindowDidResize: 1144,
|
||||
WindowDidUpdate: 1145,
|
||||
WindowDidUpdateAlpha: 1146,
|
||||
WindowDidUpdateCollectionBehavior: 1147,
|
||||
WindowDidUpdateCollectionProperties: 1148,
|
||||
WindowDidUpdateShadow: 1149,
|
||||
WindowDidUpdateTitle: 1150,
|
||||
WindowDidUpdateToolbar: 1151,
|
||||
WindowDidZoom: 1152,
|
||||
WindowFileDraggingEntered: 1153,
|
||||
WindowFileDraggingExited: 1154,
|
||||
WindowFileDraggingPerformed: 1155,
|
||||
WindowHide: 1156,
|
||||
WindowMaximise: 1157,
|
||||
WindowUnMaximise: 1158,
|
||||
WindowMinimise: 1159,
|
||||
WindowUnMinimise: 1160,
|
||||
WindowShouldClose: 1161,
|
||||
WindowShow: 1162,
|
||||
WindowWillBecomeKey: 1163,
|
||||
WindowWillBecomeMain: 1164,
|
||||
WindowWillBeginSheet: 1165,
|
||||
WindowWillChangeOrderingMode: 1166,
|
||||
WindowWillClose: 1167,
|
||||
WindowWillDeminiaturize: 1168,
|
||||
WindowWillEnterFullScreen: 1169,
|
||||
WindowWillEnterVersionBrowser: 1170,
|
||||
WindowWillExitFullScreen: 1171,
|
||||
WindowWillExitVersionBrowser: 1172,
|
||||
WindowWillFocus: 1173,
|
||||
WindowWillMiniaturize: 1174,
|
||||
WindowWillMove: 1175,
|
||||
WindowWillOrderOffScreen: 1176,
|
||||
WindowWillOrderOnScreen: 1177,
|
||||
WindowWillResignMain: 1178,
|
||||
WindowWillResize: 1179,
|
||||
WindowWillUnfocus: 1180,
|
||||
WindowWillUpdate: 1181,
|
||||
WindowWillUpdateAlpha: 1182,
|
||||
WindowWillUpdateCollectionBehavior: 1183,
|
||||
WindowWillUpdateCollectionProperties: 1184,
|
||||
WindowWillUpdateShadow: 1185,
|
||||
WindowWillUpdateTitle: 1186,
|
||||
WindowWillUpdateToolbar: 1187,
|
||||
WindowWillUpdateVisibility: 1188,
|
||||
WindowWillUseStandardFrame: 1189,
|
||||
WindowZoomIn: 1190,
|
||||
WindowZoomOut: 1191,
|
||||
WindowZoomReset: 1192,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -424,50 +422,50 @@ type windowsEvents struct {
|
|||
|
||||
func newWindowsEvents() windowsEvents {
|
||||
return windowsEvents{
|
||||
APMPowerSettingChange: 1194,
|
||||
APMPowerStatusChange: 1195,
|
||||
APMResumeAutomatic: 1196,
|
||||
APMResumeSuspend: 1197,
|
||||
APMSuspend: 1198,
|
||||
ApplicationStarted: 1199,
|
||||
SystemThemeChanged: 1200,
|
||||
WebViewNavigationCompleted: 1201,
|
||||
WindowActive: 1202,
|
||||
WindowBackgroundErase: 1203,
|
||||
WindowClickActive: 1204,
|
||||
WindowClosing: 1205,
|
||||
WindowDidMove: 1206,
|
||||
WindowDidResize: 1207,
|
||||
WindowDPIChanged: 1208,
|
||||
WindowDragDrop: 1209,
|
||||
WindowDragEnter: 1210,
|
||||
WindowDragLeave: 1211,
|
||||
WindowDragOver: 1212,
|
||||
WindowEndMove: 1213,
|
||||
WindowEndResize: 1214,
|
||||
WindowFullscreen: 1215,
|
||||
WindowHide: 1216,
|
||||
WindowInactive: 1217,
|
||||
WindowKeyDown: 1218,
|
||||
WindowKeyUp: 1219,
|
||||
WindowKillFocus: 1220,
|
||||
WindowNonClientHit: 1221,
|
||||
WindowNonClientMouseDown: 1222,
|
||||
WindowNonClientMouseLeave: 1223,
|
||||
WindowNonClientMouseMove: 1224,
|
||||
WindowNonClientMouseUp: 1225,
|
||||
WindowPaint: 1226,
|
||||
WindowRestore: 1227,
|
||||
WindowSetFocus: 1228,
|
||||
WindowShow: 1229,
|
||||
WindowStartMove: 1230,
|
||||
WindowStartResize: 1231,
|
||||
WindowUnFullscreen: 1232,
|
||||
WindowZOrderChanged: 1233,
|
||||
WindowMinimise: 1234,
|
||||
WindowUnMinimise: 1235,
|
||||
WindowMaximise: 1236,
|
||||
WindowUnMaximise: 1237,
|
||||
APMPowerSettingChange: 1193,
|
||||
APMPowerStatusChange: 1194,
|
||||
APMResumeAutomatic: 1195,
|
||||
APMResumeSuspend: 1196,
|
||||
APMSuspend: 1197,
|
||||
ApplicationStarted: 1198,
|
||||
SystemThemeChanged: 1199,
|
||||
WebViewNavigationCompleted: 1200,
|
||||
WindowActive: 1201,
|
||||
WindowBackgroundErase: 1202,
|
||||
WindowClickActive: 1203,
|
||||
WindowClosing: 1204,
|
||||
WindowDidMove: 1205,
|
||||
WindowDidResize: 1206,
|
||||
WindowDPIChanged: 1207,
|
||||
WindowDragDrop: 1208,
|
||||
WindowDragEnter: 1209,
|
||||
WindowDragLeave: 1210,
|
||||
WindowDragOver: 1211,
|
||||
WindowEndMove: 1212,
|
||||
WindowEndResize: 1213,
|
||||
WindowFullscreen: 1214,
|
||||
WindowHide: 1215,
|
||||
WindowInactive: 1216,
|
||||
WindowKeyDown: 1217,
|
||||
WindowKeyUp: 1218,
|
||||
WindowKillFocus: 1219,
|
||||
WindowNonClientHit: 1220,
|
||||
WindowNonClientMouseDown: 1221,
|
||||
WindowNonClientMouseLeave: 1222,
|
||||
WindowNonClientMouseMove: 1223,
|
||||
WindowNonClientMouseUp: 1224,
|
||||
WindowPaint: 1225,
|
||||
WindowRestore: 1226,
|
||||
WindowSetFocus: 1227,
|
||||
WindowShow: 1228,
|
||||
WindowStartMove: 1229,
|
||||
WindowStartResize: 1230,
|
||||
WindowUnFullscreen: 1231,
|
||||
WindowZOrderChanged: 1232,
|
||||
WindowMinimise: 1233,
|
||||
WindowUnMinimise: 1234,
|
||||
WindowMaximise: 1235,
|
||||
WindowUnMaximise: 1236,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -500,28 +498,28 @@ type iosEvents struct {
|
|||
|
||||
func newIOSEvents() iosEvents {
|
||||
return iosEvents{
|
||||
ApplicationDidBecomeActive: 1238,
|
||||
ApplicationDidEnterBackground: 1239,
|
||||
ApplicationDidFinishLaunching: 1240,
|
||||
ApplicationDidReceiveMemoryWarning: 1241,
|
||||
ApplicationWillEnterForeground: 1242,
|
||||
ApplicationWillResignActive: 1243,
|
||||
ApplicationWillTerminate: 1244,
|
||||
WindowDidLoad: 1245,
|
||||
WindowWillAppear: 1246,
|
||||
WindowDidAppear: 1247,
|
||||
WindowWillDisappear: 1248,
|
||||
WindowDidDisappear: 1249,
|
||||
WindowSafeAreaInsetsChanged: 1250,
|
||||
WindowOrientationChanged: 1251,
|
||||
WindowTouchBegan: 1252,
|
||||
WindowTouchMoved: 1253,
|
||||
WindowTouchEnded: 1254,
|
||||
WindowTouchCancelled: 1255,
|
||||
WebViewDidStartNavigation: 1256,
|
||||
WebViewDidFinishNavigation: 1257,
|
||||
WebViewDidFailNavigation: 1258,
|
||||
WebViewDecidePolicyForNavigationAction: 1259,
|
||||
ApplicationDidBecomeActive: 1237,
|
||||
ApplicationDidEnterBackground: 1238,
|
||||
ApplicationDidFinishLaunching: 1239,
|
||||
ApplicationDidReceiveMemoryWarning: 1240,
|
||||
ApplicationWillEnterForeground: 1241,
|
||||
ApplicationWillResignActive: 1242,
|
||||
ApplicationWillTerminate: 1243,
|
||||
WindowDidLoad: 1244,
|
||||
WindowWillAppear: 1245,
|
||||
WindowDidAppear: 1246,
|
||||
WindowWillDisappear: 1247,
|
||||
WindowDidDisappear: 1248,
|
||||
WindowSafeAreaInsetsChanged: 1249,
|
||||
WindowOrientationChanged: 1250,
|
||||
WindowTouchBegan: 1251,
|
||||
WindowTouchMoved: 1252,
|
||||
WindowTouchEnded: 1253,
|
||||
WindowTouchCancelled: 1254,
|
||||
WebViewDidStartNavigation: 1255,
|
||||
WebViewDidFinishNavigation: 1256,
|
||||
WebViewDidFailNavigation: 1257,
|
||||
WebViewDecidePolicyForNavigationAction: 1258,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -556,214 +554,213 @@ var eventToJS = map[uint]string{
|
|||
1047: "common:WindowZoomIn",
|
||||
1048: "common:WindowZoomOut",
|
||||
1049: "common:WindowZoomReset",
|
||||
1050: "common:WindowDropZoneFilesDropped",
|
||||
1051: "linux:ApplicationStartup",
|
||||
1052: "linux:SystemThemeChanged",
|
||||
1053: "linux:WindowDeleteEvent",
|
||||
1054: "linux:WindowDidMove",
|
||||
1055: "linux:WindowDidResize",
|
||||
1056: "linux:WindowFocusIn",
|
||||
1057: "linux:WindowFocusOut",
|
||||
1058: "linux:WindowLoadStarted",
|
||||
1059: "linux:WindowLoadRedirected",
|
||||
1060: "linux:WindowLoadCommitted",
|
||||
1061: "linux:WindowLoadFinished",
|
||||
1062: "mac:ApplicationDidBecomeActive",
|
||||
1063: "mac:ApplicationDidChangeBackingProperties",
|
||||
1064: "mac:ApplicationDidChangeEffectiveAppearance",
|
||||
1065: "mac:ApplicationDidChangeIcon",
|
||||
1066: "mac:ApplicationDidChangeOcclusionState",
|
||||
1067: "mac:ApplicationDidChangeScreenParameters",
|
||||
1068: "mac:ApplicationDidChangeStatusBarFrame",
|
||||
1069: "mac:ApplicationDidChangeStatusBarOrientation",
|
||||
1070: "mac:ApplicationDidChangeTheme",
|
||||
1071: "mac:ApplicationDidFinishLaunching",
|
||||
1072: "mac:ApplicationDidHide",
|
||||
1073: "mac:ApplicationDidResignActive",
|
||||
1074: "mac:ApplicationDidUnhide",
|
||||
1075: "mac:ApplicationDidUpdate",
|
||||
1076: "mac:ApplicationShouldHandleReopen",
|
||||
1077: "mac:ApplicationWillBecomeActive",
|
||||
1078: "mac:ApplicationWillFinishLaunching",
|
||||
1079: "mac:ApplicationWillHide",
|
||||
1080: "mac:ApplicationWillResignActive",
|
||||
1081: "mac:ApplicationWillTerminate",
|
||||
1082: "mac:ApplicationWillUnhide",
|
||||
1083: "mac:ApplicationWillUpdate",
|
||||
1084: "mac:MenuDidAddItem",
|
||||
1085: "mac:MenuDidBeginTracking",
|
||||
1086: "mac:MenuDidClose",
|
||||
1087: "mac:MenuDidDisplayItem",
|
||||
1088: "mac:MenuDidEndTracking",
|
||||
1089: "mac:MenuDidHighlightItem",
|
||||
1090: "mac:MenuDidOpen",
|
||||
1091: "mac:MenuDidPopUp",
|
||||
1092: "mac:MenuDidRemoveItem",
|
||||
1093: "mac:MenuDidSendAction",
|
||||
1094: "mac:MenuDidSendActionToItem",
|
||||
1095: "mac:MenuDidUpdate",
|
||||
1096: "mac:MenuWillAddItem",
|
||||
1097: "mac:MenuWillBeginTracking",
|
||||
1098: "mac:MenuWillDisplayItem",
|
||||
1099: "mac:MenuWillEndTracking",
|
||||
1100: "mac:MenuWillHighlightItem",
|
||||
1101: "mac:MenuWillOpen",
|
||||
1102: "mac:MenuWillPopUp",
|
||||
1103: "mac:MenuWillRemoveItem",
|
||||
1104: "mac:MenuWillSendAction",
|
||||
1105: "mac:MenuWillSendActionToItem",
|
||||
1106: "mac:MenuWillUpdate",
|
||||
1107: "mac:WebViewDidCommitNavigation",
|
||||
1108: "mac:WebViewDidFinishNavigation",
|
||||
1109: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation",
|
||||
1110: "mac:WebViewDidStartProvisionalNavigation",
|
||||
1111: "mac:WindowDidBecomeKey",
|
||||
1112: "mac:WindowDidBecomeMain",
|
||||
1113: "mac:WindowDidBeginSheet",
|
||||
1114: "mac:WindowDidChangeAlpha",
|
||||
1115: "mac:WindowDidChangeBackingLocation",
|
||||
1116: "mac:WindowDidChangeBackingProperties",
|
||||
1117: "mac:WindowDidChangeCollectionBehavior",
|
||||
1118: "mac:WindowDidChangeEffectiveAppearance",
|
||||
1119: "mac:WindowDidChangeOcclusionState",
|
||||
1120: "mac:WindowDidChangeOrderingMode",
|
||||
1121: "mac:WindowDidChangeScreen",
|
||||
1122: "mac:WindowDidChangeScreenParameters",
|
||||
1123: "mac:WindowDidChangeScreenProfile",
|
||||
1124: "mac:WindowDidChangeScreenSpace",
|
||||
1125: "mac:WindowDidChangeScreenSpaceProperties",
|
||||
1126: "mac:WindowDidChangeSharingType",
|
||||
1127: "mac:WindowDidChangeSpace",
|
||||
1128: "mac:WindowDidChangeSpaceOrderingMode",
|
||||
1129: "mac:WindowDidChangeTitle",
|
||||
1130: "mac:WindowDidChangeToolbar",
|
||||
1131: "mac:WindowDidDeminiaturize",
|
||||
1132: "mac:WindowDidEndSheet",
|
||||
1133: "mac:WindowDidEnterFullScreen",
|
||||
1134: "mac:WindowDidEnterVersionBrowser",
|
||||
1135: "mac:WindowDidExitFullScreen",
|
||||
1136: "mac:WindowDidExitVersionBrowser",
|
||||
1137: "mac:WindowDidExpose",
|
||||
1138: "mac:WindowDidFocus",
|
||||
1139: "mac:WindowDidMiniaturize",
|
||||
1140: "mac:WindowDidMove",
|
||||
1141: "mac:WindowDidOrderOffScreen",
|
||||
1142: "mac:WindowDidOrderOnScreen",
|
||||
1143: "mac:WindowDidResignKey",
|
||||
1144: "mac:WindowDidResignMain",
|
||||
1145: "mac:WindowDidResize",
|
||||
1146: "mac:WindowDidUpdate",
|
||||
1147: "mac:WindowDidUpdateAlpha",
|
||||
1148: "mac:WindowDidUpdateCollectionBehavior",
|
||||
1149: "mac:WindowDidUpdateCollectionProperties",
|
||||
1150: "mac:WindowDidUpdateShadow",
|
||||
1151: "mac:WindowDidUpdateTitle",
|
||||
1152: "mac:WindowDidUpdateToolbar",
|
||||
1153: "mac:WindowDidZoom",
|
||||
1154: "mac:WindowFileDraggingEntered",
|
||||
1155: "mac:WindowFileDraggingExited",
|
||||
1156: "mac:WindowFileDraggingPerformed",
|
||||
1157: "mac:WindowHide",
|
||||
1158: "mac:WindowMaximise",
|
||||
1159: "mac:WindowUnMaximise",
|
||||
1160: "mac:WindowMinimise",
|
||||
1161: "mac:WindowUnMinimise",
|
||||
1162: "mac:WindowShouldClose",
|
||||
1163: "mac:WindowShow",
|
||||
1164: "mac:WindowWillBecomeKey",
|
||||
1165: "mac:WindowWillBecomeMain",
|
||||
1166: "mac:WindowWillBeginSheet",
|
||||
1167: "mac:WindowWillChangeOrderingMode",
|
||||
1168: "mac:WindowWillClose",
|
||||
1169: "mac:WindowWillDeminiaturize",
|
||||
1170: "mac:WindowWillEnterFullScreen",
|
||||
1171: "mac:WindowWillEnterVersionBrowser",
|
||||
1172: "mac:WindowWillExitFullScreen",
|
||||
1173: "mac:WindowWillExitVersionBrowser",
|
||||
1174: "mac:WindowWillFocus",
|
||||
1175: "mac:WindowWillMiniaturize",
|
||||
1176: "mac:WindowWillMove",
|
||||
1177: "mac:WindowWillOrderOffScreen",
|
||||
1178: "mac:WindowWillOrderOnScreen",
|
||||
1179: "mac:WindowWillResignMain",
|
||||
1180: "mac:WindowWillResize",
|
||||
1181: "mac:WindowWillUnfocus",
|
||||
1182: "mac:WindowWillUpdate",
|
||||
1183: "mac:WindowWillUpdateAlpha",
|
||||
1184: "mac:WindowWillUpdateCollectionBehavior",
|
||||
1185: "mac:WindowWillUpdateCollectionProperties",
|
||||
1186: "mac:WindowWillUpdateShadow",
|
||||
1187: "mac:WindowWillUpdateTitle",
|
||||
1188: "mac:WindowWillUpdateToolbar",
|
||||
1189: "mac:WindowWillUpdateVisibility",
|
||||
1190: "mac:WindowWillUseStandardFrame",
|
||||
1191: "mac:WindowZoomIn",
|
||||
1192: "mac:WindowZoomOut",
|
||||
1193: "mac:WindowZoomReset",
|
||||
1194: "windows:APMPowerSettingChange",
|
||||
1195: "windows:APMPowerStatusChange",
|
||||
1196: "windows:APMResumeAutomatic",
|
||||
1197: "windows:APMResumeSuspend",
|
||||
1198: "windows:APMSuspend",
|
||||
1199: "windows:ApplicationStarted",
|
||||
1200: "windows:SystemThemeChanged",
|
||||
1201: "windows:WebViewNavigationCompleted",
|
||||
1202: "windows:WindowActive",
|
||||
1203: "windows:WindowBackgroundErase",
|
||||
1204: "windows:WindowClickActive",
|
||||
1205: "windows:WindowClosing",
|
||||
1206: "windows:WindowDidMove",
|
||||
1207: "windows:WindowDidResize",
|
||||
1208: "windows:WindowDPIChanged",
|
||||
1209: "windows:WindowDragDrop",
|
||||
1210: "windows:WindowDragEnter",
|
||||
1211: "windows:WindowDragLeave",
|
||||
1212: "windows:WindowDragOver",
|
||||
1213: "windows:WindowEndMove",
|
||||
1214: "windows:WindowEndResize",
|
||||
1215: "windows:WindowFullscreen",
|
||||
1216: "windows:WindowHide",
|
||||
1217: "windows:WindowInactive",
|
||||
1218: "windows:WindowKeyDown",
|
||||
1219: "windows:WindowKeyUp",
|
||||
1220: "windows:WindowKillFocus",
|
||||
1221: "windows:WindowNonClientHit",
|
||||
1222: "windows:WindowNonClientMouseDown",
|
||||
1223: "windows:WindowNonClientMouseLeave",
|
||||
1224: "windows:WindowNonClientMouseMove",
|
||||
1225: "windows:WindowNonClientMouseUp",
|
||||
1226: "windows:WindowPaint",
|
||||
1227: "windows:WindowRestore",
|
||||
1228: "windows:WindowSetFocus",
|
||||
1229: "windows:WindowShow",
|
||||
1230: "windows:WindowStartMove",
|
||||
1231: "windows:WindowStartResize",
|
||||
1232: "windows:WindowUnFullscreen",
|
||||
1233: "windows:WindowZOrderChanged",
|
||||
1234: "windows:WindowMinimise",
|
||||
1235: "windows:WindowUnMinimise",
|
||||
1236: "windows:WindowMaximise",
|
||||
1237: "windows:WindowUnMaximise",
|
||||
1238: "ios:ApplicationDidBecomeActive",
|
||||
1239: "ios:ApplicationDidEnterBackground",
|
||||
1240: "ios:ApplicationDidFinishLaunching",
|
||||
1241: "ios:ApplicationDidReceiveMemoryWarning",
|
||||
1242: "ios:ApplicationWillEnterForeground",
|
||||
1243: "ios:ApplicationWillResignActive",
|
||||
1244: "ios:ApplicationWillTerminate",
|
||||
1245: "ios:WindowDidLoad",
|
||||
1246: "ios:WindowWillAppear",
|
||||
1247: "ios:WindowDidAppear",
|
||||
1248: "ios:WindowWillDisappear",
|
||||
1249: "ios:WindowDidDisappear",
|
||||
1250: "ios:WindowSafeAreaInsetsChanged",
|
||||
1251: "ios:WindowOrientationChanged",
|
||||
1252: "ios:WindowTouchBegan",
|
||||
1253: "ios:WindowTouchMoved",
|
||||
1254: "ios:WindowTouchEnded",
|
||||
1255: "ios:WindowTouchCancelled",
|
||||
1256: "ios:WebViewDidStartNavigation",
|
||||
1257: "ios:WebViewDidFinishNavigation",
|
||||
1258: "ios:WebViewDidFailNavigation",
|
||||
1259: "ios:WebViewDecidePolicyForNavigationAction",
|
||||
1050: "linux:ApplicationStartup",
|
||||
1051: "linux:SystemThemeChanged",
|
||||
1052: "linux:WindowDeleteEvent",
|
||||
1053: "linux:WindowDidMove",
|
||||
1054: "linux:WindowDidResize",
|
||||
1055: "linux:WindowFocusIn",
|
||||
1056: "linux:WindowFocusOut",
|
||||
1057: "linux:WindowLoadStarted",
|
||||
1058: "linux:WindowLoadRedirected",
|
||||
1059: "linux:WindowLoadCommitted",
|
||||
1060: "linux:WindowLoadFinished",
|
||||
1061: "mac:ApplicationDidBecomeActive",
|
||||
1062: "mac:ApplicationDidChangeBackingProperties",
|
||||
1063: "mac:ApplicationDidChangeEffectiveAppearance",
|
||||
1064: "mac:ApplicationDidChangeIcon",
|
||||
1065: "mac:ApplicationDidChangeOcclusionState",
|
||||
1066: "mac:ApplicationDidChangeScreenParameters",
|
||||
1067: "mac:ApplicationDidChangeStatusBarFrame",
|
||||
1068: "mac:ApplicationDidChangeStatusBarOrientation",
|
||||
1069: "mac:ApplicationDidChangeTheme",
|
||||
1070: "mac:ApplicationDidFinishLaunching",
|
||||
1071: "mac:ApplicationDidHide",
|
||||
1072: "mac:ApplicationDidResignActive",
|
||||
1073: "mac:ApplicationDidUnhide",
|
||||
1074: "mac:ApplicationDidUpdate",
|
||||
1075: "mac:ApplicationShouldHandleReopen",
|
||||
1076: "mac:ApplicationWillBecomeActive",
|
||||
1077: "mac:ApplicationWillFinishLaunching",
|
||||
1078: "mac:ApplicationWillHide",
|
||||
1079: "mac:ApplicationWillResignActive",
|
||||
1080: "mac:ApplicationWillTerminate",
|
||||
1081: "mac:ApplicationWillUnhide",
|
||||
1082: "mac:ApplicationWillUpdate",
|
||||
1083: "mac:MenuDidAddItem",
|
||||
1084: "mac:MenuDidBeginTracking",
|
||||
1085: "mac:MenuDidClose",
|
||||
1086: "mac:MenuDidDisplayItem",
|
||||
1087: "mac:MenuDidEndTracking",
|
||||
1088: "mac:MenuDidHighlightItem",
|
||||
1089: "mac:MenuDidOpen",
|
||||
1090: "mac:MenuDidPopUp",
|
||||
1091: "mac:MenuDidRemoveItem",
|
||||
1092: "mac:MenuDidSendAction",
|
||||
1093: "mac:MenuDidSendActionToItem",
|
||||
1094: "mac:MenuDidUpdate",
|
||||
1095: "mac:MenuWillAddItem",
|
||||
1096: "mac:MenuWillBeginTracking",
|
||||
1097: "mac:MenuWillDisplayItem",
|
||||
1098: "mac:MenuWillEndTracking",
|
||||
1099: "mac:MenuWillHighlightItem",
|
||||
1100: "mac:MenuWillOpen",
|
||||
1101: "mac:MenuWillPopUp",
|
||||
1102: "mac:MenuWillRemoveItem",
|
||||
1103: "mac:MenuWillSendAction",
|
||||
1104: "mac:MenuWillSendActionToItem",
|
||||
1105: "mac:MenuWillUpdate",
|
||||
1106: "mac:WebViewDidCommitNavigation",
|
||||
1107: "mac:WebViewDidFinishNavigation",
|
||||
1108: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation",
|
||||
1109: "mac:WebViewDidStartProvisionalNavigation",
|
||||
1110: "mac:WindowDidBecomeKey",
|
||||
1111: "mac:WindowDidBecomeMain",
|
||||
1112: "mac:WindowDidBeginSheet",
|
||||
1113: "mac:WindowDidChangeAlpha",
|
||||
1114: "mac:WindowDidChangeBackingLocation",
|
||||
1115: "mac:WindowDidChangeBackingProperties",
|
||||
1116: "mac:WindowDidChangeCollectionBehavior",
|
||||
1117: "mac:WindowDidChangeEffectiveAppearance",
|
||||
1118: "mac:WindowDidChangeOcclusionState",
|
||||
1119: "mac:WindowDidChangeOrderingMode",
|
||||
1120: "mac:WindowDidChangeScreen",
|
||||
1121: "mac:WindowDidChangeScreenParameters",
|
||||
1122: "mac:WindowDidChangeScreenProfile",
|
||||
1123: "mac:WindowDidChangeScreenSpace",
|
||||
1124: "mac:WindowDidChangeScreenSpaceProperties",
|
||||
1125: "mac:WindowDidChangeSharingType",
|
||||
1126: "mac:WindowDidChangeSpace",
|
||||
1127: "mac:WindowDidChangeSpaceOrderingMode",
|
||||
1128: "mac:WindowDidChangeTitle",
|
||||
1129: "mac:WindowDidChangeToolbar",
|
||||
1130: "mac:WindowDidDeminiaturize",
|
||||
1131: "mac:WindowDidEndSheet",
|
||||
1132: "mac:WindowDidEnterFullScreen",
|
||||
1133: "mac:WindowDidEnterVersionBrowser",
|
||||
1134: "mac:WindowDidExitFullScreen",
|
||||
1135: "mac:WindowDidExitVersionBrowser",
|
||||
1136: "mac:WindowDidExpose",
|
||||
1137: "mac:WindowDidFocus",
|
||||
1138: "mac:WindowDidMiniaturize",
|
||||
1139: "mac:WindowDidMove",
|
||||
1140: "mac:WindowDidOrderOffScreen",
|
||||
1141: "mac:WindowDidOrderOnScreen",
|
||||
1142: "mac:WindowDidResignKey",
|
||||
1143: "mac:WindowDidResignMain",
|
||||
1144: "mac:WindowDidResize",
|
||||
1145: "mac:WindowDidUpdate",
|
||||
1146: "mac:WindowDidUpdateAlpha",
|
||||
1147: "mac:WindowDidUpdateCollectionBehavior",
|
||||
1148: "mac:WindowDidUpdateCollectionProperties",
|
||||
1149: "mac:WindowDidUpdateShadow",
|
||||
1150: "mac:WindowDidUpdateTitle",
|
||||
1151: "mac:WindowDidUpdateToolbar",
|
||||
1152: "mac:WindowDidZoom",
|
||||
1153: "mac:WindowFileDraggingEntered",
|
||||
1154: "mac:WindowFileDraggingExited",
|
||||
1155: "mac:WindowFileDraggingPerformed",
|
||||
1156: "mac:WindowHide",
|
||||
1157: "mac:WindowMaximise",
|
||||
1158: "mac:WindowUnMaximise",
|
||||
1159: "mac:WindowMinimise",
|
||||
1160: "mac:WindowUnMinimise",
|
||||
1161: "mac:WindowShouldClose",
|
||||
1162: "mac:WindowShow",
|
||||
1163: "mac:WindowWillBecomeKey",
|
||||
1164: "mac:WindowWillBecomeMain",
|
||||
1165: "mac:WindowWillBeginSheet",
|
||||
1166: "mac:WindowWillChangeOrderingMode",
|
||||
1167: "mac:WindowWillClose",
|
||||
1168: "mac:WindowWillDeminiaturize",
|
||||
1169: "mac:WindowWillEnterFullScreen",
|
||||
1170: "mac:WindowWillEnterVersionBrowser",
|
||||
1171: "mac:WindowWillExitFullScreen",
|
||||
1172: "mac:WindowWillExitVersionBrowser",
|
||||
1173: "mac:WindowWillFocus",
|
||||
1174: "mac:WindowWillMiniaturize",
|
||||
1175: "mac:WindowWillMove",
|
||||
1176: "mac:WindowWillOrderOffScreen",
|
||||
1177: "mac:WindowWillOrderOnScreen",
|
||||
1178: "mac:WindowWillResignMain",
|
||||
1179: "mac:WindowWillResize",
|
||||
1180: "mac:WindowWillUnfocus",
|
||||
1181: "mac:WindowWillUpdate",
|
||||
1182: "mac:WindowWillUpdateAlpha",
|
||||
1183: "mac:WindowWillUpdateCollectionBehavior",
|
||||
1184: "mac:WindowWillUpdateCollectionProperties",
|
||||
1185: "mac:WindowWillUpdateShadow",
|
||||
1186: "mac:WindowWillUpdateTitle",
|
||||
1187: "mac:WindowWillUpdateToolbar",
|
||||
1188: "mac:WindowWillUpdateVisibility",
|
||||
1189: "mac:WindowWillUseStandardFrame",
|
||||
1190: "mac:WindowZoomIn",
|
||||
1191: "mac:WindowZoomOut",
|
||||
1192: "mac:WindowZoomReset",
|
||||
1193: "windows:APMPowerSettingChange",
|
||||
1194: "windows:APMPowerStatusChange",
|
||||
1195: "windows:APMResumeAutomatic",
|
||||
1196: "windows:APMResumeSuspend",
|
||||
1197: "windows:APMSuspend",
|
||||
1198: "windows:ApplicationStarted",
|
||||
1199: "windows:SystemThemeChanged",
|
||||
1200: "windows:WebViewNavigationCompleted",
|
||||
1201: "windows:WindowActive",
|
||||
1202: "windows:WindowBackgroundErase",
|
||||
1203: "windows:WindowClickActive",
|
||||
1204: "windows:WindowClosing",
|
||||
1205: "windows:WindowDidMove",
|
||||
1206: "windows:WindowDidResize",
|
||||
1207: "windows:WindowDPIChanged",
|
||||
1208: "windows:WindowDragDrop",
|
||||
1209: "windows:WindowDragEnter",
|
||||
1210: "windows:WindowDragLeave",
|
||||
1211: "windows:WindowDragOver",
|
||||
1212: "windows:WindowEndMove",
|
||||
1213: "windows:WindowEndResize",
|
||||
1214: "windows:WindowFullscreen",
|
||||
1215: "windows:WindowHide",
|
||||
1216: "windows:WindowInactive",
|
||||
1217: "windows:WindowKeyDown",
|
||||
1218: "windows:WindowKeyUp",
|
||||
1219: "windows:WindowKillFocus",
|
||||
1220: "windows:WindowNonClientHit",
|
||||
1221: "windows:WindowNonClientMouseDown",
|
||||
1222: "windows:WindowNonClientMouseLeave",
|
||||
1223: "windows:WindowNonClientMouseMove",
|
||||
1224: "windows:WindowNonClientMouseUp",
|
||||
1225: "windows:WindowPaint",
|
||||
1226: "windows:WindowRestore",
|
||||
1227: "windows:WindowSetFocus",
|
||||
1228: "windows:WindowShow",
|
||||
1229: "windows:WindowStartMove",
|
||||
1230: "windows:WindowStartResize",
|
||||
1231: "windows:WindowUnFullscreen",
|
||||
1232: "windows:WindowZOrderChanged",
|
||||
1233: "windows:WindowMinimise",
|
||||
1234: "windows:WindowUnMinimise",
|
||||
1235: "windows:WindowMaximise",
|
||||
1236: "windows:WindowUnMaximise",
|
||||
1237: "ios:ApplicationDidBecomeActive",
|
||||
1238: "ios:ApplicationDidEnterBackground",
|
||||
1239: "ios:ApplicationDidFinishLaunching",
|
||||
1240: "ios:ApplicationDidReceiveMemoryWarning",
|
||||
1241: "ios:ApplicationWillEnterForeground",
|
||||
1242: "ios:ApplicationWillResignActive",
|
||||
1243: "ios:ApplicationWillTerminate",
|
||||
1244: "ios:WindowDidLoad",
|
||||
1245: "ios:WindowWillAppear",
|
||||
1246: "ios:WindowDidAppear",
|
||||
1247: "ios:WindowWillDisappear",
|
||||
1248: "ios:WindowDidDisappear",
|
||||
1249: "ios:WindowSafeAreaInsetsChanged",
|
||||
1250: "ios:WindowOrientationChanged",
|
||||
1251: "ios:WindowTouchBegan",
|
||||
1252: "ios:WindowTouchMoved",
|
||||
1253: "ios:WindowTouchEnded",
|
||||
1254: "ios:WindowTouchCancelled",
|
||||
1255: "ios:WebViewDidStartNavigation",
|
||||
1256: "ios:WebViewDidFinishNavigation",
|
||||
1257: "ios:WebViewDidFailNavigation",
|
||||
1258: "ios:WebViewDecidePolicyForNavigationAction",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ common:WindowZoom
|
|||
common:WindowZoomIn
|
||||
common:WindowZoomOut
|
||||
common:WindowZoomReset
|
||||
common:WindowDropZoneFilesDropped
|
||||
linux:ApplicationStartup
|
||||
linux:SystemThemeChanged
|
||||
linux:WindowDeleteEvent
|
||||
|
|
|
|||
|
|
@ -6,140 +6,140 @@
|
|||
extern void processApplicationEvent(unsigned int, void* data);
|
||||
extern void processWindowEvent(unsigned int, unsigned int);
|
||||
|
||||
#define EventApplicationDidBecomeActive 1062
|
||||
#define EventApplicationDidChangeBackingProperties 1063
|
||||
#define EventApplicationDidChangeEffectiveAppearance 1064
|
||||
#define EventApplicationDidChangeIcon 1065
|
||||
#define EventApplicationDidChangeOcclusionState 1066
|
||||
#define EventApplicationDidChangeScreenParameters 1067
|
||||
#define EventApplicationDidChangeStatusBarFrame 1068
|
||||
#define EventApplicationDidChangeStatusBarOrientation 1069
|
||||
#define EventApplicationDidChangeTheme 1070
|
||||
#define EventApplicationDidFinishLaunching 1071
|
||||
#define EventApplicationDidHide 1072
|
||||
#define EventApplicationDidResignActive 1073
|
||||
#define EventApplicationDidUnhide 1074
|
||||
#define EventApplicationDidUpdate 1075
|
||||
#define EventApplicationShouldHandleReopen 1076
|
||||
#define EventApplicationWillBecomeActive 1077
|
||||
#define EventApplicationWillFinishLaunching 1078
|
||||
#define EventApplicationWillHide 1079
|
||||
#define EventApplicationWillResignActive 1080
|
||||
#define EventApplicationWillTerminate 1081
|
||||
#define EventApplicationWillUnhide 1082
|
||||
#define EventApplicationWillUpdate 1083
|
||||
#define EventMenuDidAddItem 1084
|
||||
#define EventMenuDidBeginTracking 1085
|
||||
#define EventMenuDidClose 1086
|
||||
#define EventMenuDidDisplayItem 1087
|
||||
#define EventMenuDidEndTracking 1088
|
||||
#define EventMenuDidHighlightItem 1089
|
||||
#define EventMenuDidOpen 1090
|
||||
#define EventMenuDidPopUp 1091
|
||||
#define EventMenuDidRemoveItem 1092
|
||||
#define EventMenuDidSendAction 1093
|
||||
#define EventMenuDidSendActionToItem 1094
|
||||
#define EventMenuDidUpdate 1095
|
||||
#define EventMenuWillAddItem 1096
|
||||
#define EventMenuWillBeginTracking 1097
|
||||
#define EventMenuWillDisplayItem 1098
|
||||
#define EventMenuWillEndTracking 1099
|
||||
#define EventMenuWillHighlightItem 1100
|
||||
#define EventMenuWillOpen 1101
|
||||
#define EventMenuWillPopUp 1102
|
||||
#define EventMenuWillRemoveItem 1103
|
||||
#define EventMenuWillSendAction 1104
|
||||
#define EventMenuWillSendActionToItem 1105
|
||||
#define EventMenuWillUpdate 1106
|
||||
#define EventWebViewDidCommitNavigation 1107
|
||||
#define EventWebViewDidFinishNavigation 1108
|
||||
#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1109
|
||||
#define EventWebViewDidStartProvisionalNavigation 1110
|
||||
#define EventWindowDidBecomeKey 1111
|
||||
#define EventWindowDidBecomeMain 1112
|
||||
#define EventWindowDidBeginSheet 1113
|
||||
#define EventWindowDidChangeAlpha 1114
|
||||
#define EventWindowDidChangeBackingLocation 1115
|
||||
#define EventWindowDidChangeBackingProperties 1116
|
||||
#define EventWindowDidChangeCollectionBehavior 1117
|
||||
#define EventWindowDidChangeEffectiveAppearance 1118
|
||||
#define EventWindowDidChangeOcclusionState 1119
|
||||
#define EventWindowDidChangeOrderingMode 1120
|
||||
#define EventWindowDidChangeScreen 1121
|
||||
#define EventWindowDidChangeScreenParameters 1122
|
||||
#define EventWindowDidChangeScreenProfile 1123
|
||||
#define EventWindowDidChangeScreenSpace 1124
|
||||
#define EventWindowDidChangeScreenSpaceProperties 1125
|
||||
#define EventWindowDidChangeSharingType 1126
|
||||
#define EventWindowDidChangeSpace 1127
|
||||
#define EventWindowDidChangeSpaceOrderingMode 1128
|
||||
#define EventWindowDidChangeTitle 1129
|
||||
#define EventWindowDidChangeToolbar 1130
|
||||
#define EventWindowDidDeminiaturize 1131
|
||||
#define EventWindowDidEndSheet 1132
|
||||
#define EventWindowDidEnterFullScreen 1133
|
||||
#define EventWindowDidEnterVersionBrowser 1134
|
||||
#define EventWindowDidExitFullScreen 1135
|
||||
#define EventWindowDidExitVersionBrowser 1136
|
||||
#define EventWindowDidExpose 1137
|
||||
#define EventWindowDidFocus 1138
|
||||
#define EventWindowDidMiniaturize 1139
|
||||
#define EventWindowDidMove 1140
|
||||
#define EventWindowDidOrderOffScreen 1141
|
||||
#define EventWindowDidOrderOnScreen 1142
|
||||
#define EventWindowDidResignKey 1143
|
||||
#define EventWindowDidResignMain 1144
|
||||
#define EventWindowDidResize 1145
|
||||
#define EventWindowDidUpdate 1146
|
||||
#define EventWindowDidUpdateAlpha 1147
|
||||
#define EventWindowDidUpdateCollectionBehavior 1148
|
||||
#define EventWindowDidUpdateCollectionProperties 1149
|
||||
#define EventWindowDidUpdateShadow 1150
|
||||
#define EventWindowDidUpdateTitle 1151
|
||||
#define EventWindowDidUpdateToolbar 1152
|
||||
#define EventWindowDidZoom 1153
|
||||
#define EventWindowFileDraggingEntered 1154
|
||||
#define EventWindowFileDraggingExited 1155
|
||||
#define EventWindowFileDraggingPerformed 1156
|
||||
#define EventWindowHide 1157
|
||||
#define EventWindowMaximise 1158
|
||||
#define EventWindowUnMaximise 1159
|
||||
#define EventWindowMinimise 1160
|
||||
#define EventWindowUnMinimise 1161
|
||||
#define EventWindowShouldClose 1162
|
||||
#define EventWindowShow 1163
|
||||
#define EventWindowWillBecomeKey 1164
|
||||
#define EventWindowWillBecomeMain 1165
|
||||
#define EventWindowWillBeginSheet 1166
|
||||
#define EventWindowWillChangeOrderingMode 1167
|
||||
#define EventWindowWillClose 1168
|
||||
#define EventWindowWillDeminiaturize 1169
|
||||
#define EventWindowWillEnterFullScreen 1170
|
||||
#define EventWindowWillEnterVersionBrowser 1171
|
||||
#define EventWindowWillExitFullScreen 1172
|
||||
#define EventWindowWillExitVersionBrowser 1173
|
||||
#define EventWindowWillFocus 1174
|
||||
#define EventWindowWillMiniaturize 1175
|
||||
#define EventWindowWillMove 1176
|
||||
#define EventWindowWillOrderOffScreen 1177
|
||||
#define EventWindowWillOrderOnScreen 1178
|
||||
#define EventWindowWillResignMain 1179
|
||||
#define EventWindowWillResize 1180
|
||||
#define EventWindowWillUnfocus 1181
|
||||
#define EventWindowWillUpdate 1182
|
||||
#define EventWindowWillUpdateAlpha 1183
|
||||
#define EventWindowWillUpdateCollectionBehavior 1184
|
||||
#define EventWindowWillUpdateCollectionProperties 1185
|
||||
#define EventWindowWillUpdateShadow 1186
|
||||
#define EventWindowWillUpdateTitle 1187
|
||||
#define EventWindowWillUpdateToolbar 1188
|
||||
#define EventWindowWillUpdateVisibility 1189
|
||||
#define EventWindowWillUseStandardFrame 1190
|
||||
#define EventWindowZoomIn 1191
|
||||
#define EventWindowZoomOut 1192
|
||||
#define EventWindowZoomReset 1193
|
||||
#define EventApplicationDidBecomeActive 1061
|
||||
#define EventApplicationDidChangeBackingProperties 1062
|
||||
#define EventApplicationDidChangeEffectiveAppearance 1063
|
||||
#define EventApplicationDidChangeIcon 1064
|
||||
#define EventApplicationDidChangeOcclusionState 1065
|
||||
#define EventApplicationDidChangeScreenParameters 1066
|
||||
#define EventApplicationDidChangeStatusBarFrame 1067
|
||||
#define EventApplicationDidChangeStatusBarOrientation 1068
|
||||
#define EventApplicationDidChangeTheme 1069
|
||||
#define EventApplicationDidFinishLaunching 1070
|
||||
#define EventApplicationDidHide 1071
|
||||
#define EventApplicationDidResignActive 1072
|
||||
#define EventApplicationDidUnhide 1073
|
||||
#define EventApplicationDidUpdate 1074
|
||||
#define EventApplicationShouldHandleReopen 1075
|
||||
#define EventApplicationWillBecomeActive 1076
|
||||
#define EventApplicationWillFinishLaunching 1077
|
||||
#define EventApplicationWillHide 1078
|
||||
#define EventApplicationWillResignActive 1079
|
||||
#define EventApplicationWillTerminate 1080
|
||||
#define EventApplicationWillUnhide 1081
|
||||
#define EventApplicationWillUpdate 1082
|
||||
#define EventMenuDidAddItem 1083
|
||||
#define EventMenuDidBeginTracking 1084
|
||||
#define EventMenuDidClose 1085
|
||||
#define EventMenuDidDisplayItem 1086
|
||||
#define EventMenuDidEndTracking 1087
|
||||
#define EventMenuDidHighlightItem 1088
|
||||
#define EventMenuDidOpen 1089
|
||||
#define EventMenuDidPopUp 1090
|
||||
#define EventMenuDidRemoveItem 1091
|
||||
#define EventMenuDidSendAction 1092
|
||||
#define EventMenuDidSendActionToItem 1093
|
||||
#define EventMenuDidUpdate 1094
|
||||
#define EventMenuWillAddItem 1095
|
||||
#define EventMenuWillBeginTracking 1096
|
||||
#define EventMenuWillDisplayItem 1097
|
||||
#define EventMenuWillEndTracking 1098
|
||||
#define EventMenuWillHighlightItem 1099
|
||||
#define EventMenuWillOpen 1100
|
||||
#define EventMenuWillPopUp 1101
|
||||
#define EventMenuWillRemoveItem 1102
|
||||
#define EventMenuWillSendAction 1103
|
||||
#define EventMenuWillSendActionToItem 1104
|
||||
#define EventMenuWillUpdate 1105
|
||||
#define EventWebViewDidCommitNavigation 1106
|
||||
#define EventWebViewDidFinishNavigation 1107
|
||||
#define EventWebViewDidReceiveServerRedirectForProvisionalNavigation 1108
|
||||
#define EventWebViewDidStartProvisionalNavigation 1109
|
||||
#define EventWindowDidBecomeKey 1110
|
||||
#define EventWindowDidBecomeMain 1111
|
||||
#define EventWindowDidBeginSheet 1112
|
||||
#define EventWindowDidChangeAlpha 1113
|
||||
#define EventWindowDidChangeBackingLocation 1114
|
||||
#define EventWindowDidChangeBackingProperties 1115
|
||||
#define EventWindowDidChangeCollectionBehavior 1116
|
||||
#define EventWindowDidChangeEffectiveAppearance 1117
|
||||
#define EventWindowDidChangeOcclusionState 1118
|
||||
#define EventWindowDidChangeOrderingMode 1119
|
||||
#define EventWindowDidChangeScreen 1120
|
||||
#define EventWindowDidChangeScreenParameters 1121
|
||||
#define EventWindowDidChangeScreenProfile 1122
|
||||
#define EventWindowDidChangeScreenSpace 1123
|
||||
#define EventWindowDidChangeScreenSpaceProperties 1124
|
||||
#define EventWindowDidChangeSharingType 1125
|
||||
#define EventWindowDidChangeSpace 1126
|
||||
#define EventWindowDidChangeSpaceOrderingMode 1127
|
||||
#define EventWindowDidChangeTitle 1128
|
||||
#define EventWindowDidChangeToolbar 1129
|
||||
#define EventWindowDidDeminiaturize 1130
|
||||
#define EventWindowDidEndSheet 1131
|
||||
#define EventWindowDidEnterFullScreen 1132
|
||||
#define EventWindowDidEnterVersionBrowser 1133
|
||||
#define EventWindowDidExitFullScreen 1134
|
||||
#define EventWindowDidExitVersionBrowser 1135
|
||||
#define EventWindowDidExpose 1136
|
||||
#define EventWindowDidFocus 1137
|
||||
#define EventWindowDidMiniaturize 1138
|
||||
#define EventWindowDidMove 1139
|
||||
#define EventWindowDidOrderOffScreen 1140
|
||||
#define EventWindowDidOrderOnScreen 1141
|
||||
#define EventWindowDidResignKey 1142
|
||||
#define EventWindowDidResignMain 1143
|
||||
#define EventWindowDidResize 1144
|
||||
#define EventWindowDidUpdate 1145
|
||||
#define EventWindowDidUpdateAlpha 1146
|
||||
#define EventWindowDidUpdateCollectionBehavior 1147
|
||||
#define EventWindowDidUpdateCollectionProperties 1148
|
||||
#define EventWindowDidUpdateShadow 1149
|
||||
#define EventWindowDidUpdateTitle 1150
|
||||
#define EventWindowDidUpdateToolbar 1151
|
||||
#define EventWindowDidZoom 1152
|
||||
#define EventWindowFileDraggingEntered 1153
|
||||
#define EventWindowFileDraggingExited 1154
|
||||
#define EventWindowFileDraggingPerformed 1155
|
||||
#define EventWindowHide 1156
|
||||
#define EventWindowMaximise 1157
|
||||
#define EventWindowUnMaximise 1158
|
||||
#define EventWindowMinimise 1159
|
||||
#define EventWindowUnMinimise 1160
|
||||
#define EventWindowShouldClose 1161
|
||||
#define EventWindowShow 1162
|
||||
#define EventWindowWillBecomeKey 1163
|
||||
#define EventWindowWillBecomeMain 1164
|
||||
#define EventWindowWillBeginSheet 1165
|
||||
#define EventWindowWillChangeOrderingMode 1166
|
||||
#define EventWindowWillClose 1167
|
||||
#define EventWindowWillDeminiaturize 1168
|
||||
#define EventWindowWillEnterFullScreen 1169
|
||||
#define EventWindowWillEnterVersionBrowser 1170
|
||||
#define EventWindowWillExitFullScreen 1171
|
||||
#define EventWindowWillExitVersionBrowser 1172
|
||||
#define EventWindowWillFocus 1173
|
||||
#define EventWindowWillMiniaturize 1174
|
||||
#define EventWindowWillMove 1175
|
||||
#define EventWindowWillOrderOffScreen 1176
|
||||
#define EventWindowWillOrderOnScreen 1177
|
||||
#define EventWindowWillResignMain 1178
|
||||
#define EventWindowWillResize 1179
|
||||
#define EventWindowWillUnfocus 1180
|
||||
#define EventWindowWillUpdate 1181
|
||||
#define EventWindowWillUpdateAlpha 1182
|
||||
#define EventWindowWillUpdateCollectionBehavior 1183
|
||||
#define EventWindowWillUpdateCollectionProperties 1184
|
||||
#define EventWindowWillUpdateShadow 1185
|
||||
#define EventWindowWillUpdateTitle 1186
|
||||
#define EventWindowWillUpdateToolbar 1187
|
||||
#define EventWindowWillUpdateVisibility 1188
|
||||
#define EventWindowWillUseStandardFrame 1189
|
||||
#define EventWindowZoomIn 1190
|
||||
#define EventWindowZoomOut 1191
|
||||
#define EventWindowZoomReset 1192
|
||||
|
||||
#define MAX_EVENTS 1194
|
||||
#define MAX_EVENTS 1193
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -6,30 +6,30 @@
|
|||
extern void processApplicationEvent(unsigned int, void* data);
|
||||
extern void processWindowEvent(unsigned int, unsigned int);
|
||||
|
||||
#define EventApplicationDidBecomeActive 1238
|
||||
#define EventApplicationDidEnterBackground 1239
|
||||
#define EventApplicationDidFinishLaunching 1240
|
||||
#define EventApplicationDidReceiveMemoryWarning 1241
|
||||
#define EventApplicationWillEnterForeground 1242
|
||||
#define EventApplicationWillResignActive 1243
|
||||
#define EventApplicationWillTerminate 1244
|
||||
#define EventWindowDidLoad 1245
|
||||
#define EventWindowWillAppear 1246
|
||||
#define EventWindowDidAppear 1247
|
||||
#define EventWindowWillDisappear 1248
|
||||
#define EventWindowDidDisappear 1249
|
||||
#define EventWindowSafeAreaInsetsChanged 1250
|
||||
#define EventWindowOrientationChanged 1251
|
||||
#define EventWindowTouchBegan 1252
|
||||
#define EventWindowTouchMoved 1253
|
||||
#define EventWindowTouchEnded 1254
|
||||
#define EventWindowTouchCancelled 1255
|
||||
#define EventWebViewDidStartNavigation 1256
|
||||
#define EventWebViewDidFinishNavigation 1257
|
||||
#define EventWebViewDidFailNavigation 1258
|
||||
#define EventWebViewDecidePolicyForNavigationAction 1259
|
||||
#define EventApplicationDidBecomeActive 1237
|
||||
#define EventApplicationDidEnterBackground 1238
|
||||
#define EventApplicationDidFinishLaunching 1239
|
||||
#define EventApplicationDidReceiveMemoryWarning 1240
|
||||
#define EventApplicationWillEnterForeground 1241
|
||||
#define EventApplicationWillResignActive 1242
|
||||
#define EventApplicationWillTerminate 1243
|
||||
#define EventWindowDidLoad 1244
|
||||
#define EventWindowWillAppear 1245
|
||||
#define EventWindowDidAppear 1246
|
||||
#define EventWindowWillDisappear 1247
|
||||
#define EventWindowDidDisappear 1248
|
||||
#define EventWindowSafeAreaInsetsChanged 1249
|
||||
#define EventWindowOrientationChanged 1250
|
||||
#define EventWindowTouchBegan 1251
|
||||
#define EventWindowTouchMoved 1252
|
||||
#define EventWindowTouchEnded 1253
|
||||
#define EventWindowTouchCancelled 1254
|
||||
#define EventWebViewDidStartNavigation 1255
|
||||
#define EventWebViewDidFinishNavigation 1256
|
||||
#define EventWebViewDidFailNavigation 1257
|
||||
#define EventWebViewDecidePolicyForNavigationAction 1258
|
||||
|
||||
#define MAX_EVENTS 1260
|
||||
#define MAX_EVENTS 1259
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -6,19 +6,19 @@
|
|||
extern void processApplicationEvent(unsigned int, void* data);
|
||||
extern void processWindowEvent(unsigned int, unsigned int);
|
||||
|
||||
#define EventApplicationStartup 1051
|
||||
#define EventSystemThemeChanged 1052
|
||||
#define EventWindowDeleteEvent 1053
|
||||
#define EventWindowDidMove 1054
|
||||
#define EventWindowDidResize 1055
|
||||
#define EventWindowFocusIn 1056
|
||||
#define EventWindowFocusOut 1057
|
||||
#define EventWindowLoadStarted 1058
|
||||
#define EventWindowLoadRedirected 1059
|
||||
#define EventWindowLoadCommitted 1060
|
||||
#define EventWindowLoadFinished 1061
|
||||
#define EventApplicationStartup 1050
|
||||
#define EventSystemThemeChanged 1051
|
||||
#define EventWindowDeleteEvent 1052
|
||||
#define EventWindowDidMove 1053
|
||||
#define EventWindowDidResize 1054
|
||||
#define EventWindowFocusIn 1055
|
||||
#define EventWindowFocusOut 1056
|
||||
#define EventWindowLoadStarted 1057
|
||||
#define EventWindowLoadRedirected 1058
|
||||
#define EventWindowLoadCommitted 1059
|
||||
#define EventWindowLoadFinished 1060
|
||||
|
||||
#define MAX_EVENTS 1062
|
||||
#define MAX_EVENTS 1061
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -6,218 +6,217 @@ func IsKnownEvent(name string) bool {
|
|||
}
|
||||
|
||||
var knownEvents = map[string]struct{}{
|
||||
"common:ApplicationOpenedWithFile": {},
|
||||
"common:ApplicationStarted": {},
|
||||
"common:ApplicationLaunchedWithUrl": {},
|
||||
"common:ThemeChanged": {},
|
||||
"common:WindowClosing": {},
|
||||
"common:WindowDidMove": {},
|
||||
"common:WindowDidResize": {},
|
||||
"common:WindowDPIChanged": {},
|
||||
"common:WindowFilesDropped": {},
|
||||
"common:WindowFocus": {},
|
||||
"common:WindowFullscreen": {},
|
||||
"common:WindowHide": {},
|
||||
"common:WindowLostFocus": {},
|
||||
"common:WindowMaximise": {},
|
||||
"common:WindowMinimise": {},
|
||||
"common:WindowToggleFrameless": {},
|
||||
"common:WindowRestore": {},
|
||||
"common:WindowRuntimeReady": {},
|
||||
"common:WindowShow": {},
|
||||
"common:WindowUnFullscreen": {},
|
||||
"common:WindowUnMaximise": {},
|
||||
"common:WindowUnMinimise": {},
|
||||
"common:WindowZoom": {},
|
||||
"common:WindowZoomIn": {},
|
||||
"common:WindowZoomOut": {},
|
||||
"common:WindowZoomReset": {},
|
||||
"common:WindowDropZoneFilesDropped": {},
|
||||
"linux:ApplicationStartup": {},
|
||||
"linux:SystemThemeChanged": {},
|
||||
"linux:WindowDeleteEvent": {},
|
||||
"linux:WindowDidMove": {},
|
||||
"linux:WindowDidResize": {},
|
||||
"linux:WindowFocusIn": {},
|
||||
"linux:WindowFocusOut": {},
|
||||
"linux:WindowLoadStarted": {},
|
||||
"linux:WindowLoadRedirected": {},
|
||||
"linux:WindowLoadCommitted": {},
|
||||
"linux:WindowLoadFinished": {},
|
||||
"mac:ApplicationDidBecomeActive": {},
|
||||
"mac:ApplicationDidChangeBackingProperties": {},
|
||||
"mac:ApplicationDidChangeEffectiveAppearance": {},
|
||||
"mac:ApplicationDidChangeIcon": {},
|
||||
"mac:ApplicationDidChangeOcclusionState": {},
|
||||
"mac:ApplicationDidChangeScreenParameters": {},
|
||||
"mac:ApplicationDidChangeStatusBarFrame": {},
|
||||
"mac:ApplicationDidChangeStatusBarOrientation": {},
|
||||
"mac:ApplicationDidChangeTheme": {},
|
||||
"mac:ApplicationDidFinishLaunching": {},
|
||||
"mac:ApplicationDidHide": {},
|
||||
"mac:ApplicationDidResignActive": {},
|
||||
"mac:ApplicationDidUnhide": {},
|
||||
"mac:ApplicationDidUpdate": {},
|
||||
"mac:ApplicationShouldHandleReopen": {},
|
||||
"mac:ApplicationWillBecomeActive": {},
|
||||
"mac:ApplicationWillFinishLaunching": {},
|
||||
"mac:ApplicationWillHide": {},
|
||||
"mac:ApplicationWillResignActive": {},
|
||||
"mac:ApplicationWillTerminate": {},
|
||||
"mac:ApplicationWillUnhide": {},
|
||||
"mac:ApplicationWillUpdate": {},
|
||||
"mac:MenuDidAddItem": {},
|
||||
"mac:MenuDidBeginTracking": {},
|
||||
"mac:MenuDidClose": {},
|
||||
"mac:MenuDidDisplayItem": {},
|
||||
"mac:MenuDidEndTracking": {},
|
||||
"mac:MenuDidHighlightItem": {},
|
||||
"mac:MenuDidOpen": {},
|
||||
"mac:MenuDidPopUp": {},
|
||||
"mac:MenuDidRemoveItem": {},
|
||||
"mac:MenuDidSendAction": {},
|
||||
"mac:MenuDidSendActionToItem": {},
|
||||
"mac:MenuDidUpdate": {},
|
||||
"mac:MenuWillAddItem": {},
|
||||
"mac:MenuWillBeginTracking": {},
|
||||
"mac:MenuWillDisplayItem": {},
|
||||
"mac:MenuWillEndTracking": {},
|
||||
"mac:MenuWillHighlightItem": {},
|
||||
"mac:MenuWillOpen": {},
|
||||
"mac:MenuWillPopUp": {},
|
||||
"mac:MenuWillRemoveItem": {},
|
||||
"mac:MenuWillSendAction": {},
|
||||
"mac:MenuWillSendActionToItem": {},
|
||||
"mac:MenuWillUpdate": {},
|
||||
"mac:WebViewDidCommitNavigation": {},
|
||||
"mac:WebViewDidFinishNavigation": {},
|
||||
"common:ApplicationOpenedWithFile": {},
|
||||
"common:ApplicationStarted": {},
|
||||
"common:ApplicationLaunchedWithUrl": {},
|
||||
"common:ThemeChanged": {},
|
||||
"common:WindowClosing": {},
|
||||
"common:WindowDidMove": {},
|
||||
"common:WindowDidResize": {},
|
||||
"common:WindowDPIChanged": {},
|
||||
"common:WindowFilesDropped": {},
|
||||
"common:WindowFocus": {},
|
||||
"common:WindowFullscreen": {},
|
||||
"common:WindowHide": {},
|
||||
"common:WindowLostFocus": {},
|
||||
"common:WindowMaximise": {},
|
||||
"common:WindowMinimise": {},
|
||||
"common:WindowToggleFrameless": {},
|
||||
"common:WindowRestore": {},
|
||||
"common:WindowRuntimeReady": {},
|
||||
"common:WindowShow": {},
|
||||
"common:WindowUnFullscreen": {},
|
||||
"common:WindowUnMaximise": {},
|
||||
"common:WindowUnMinimise": {},
|
||||
"common:WindowZoom": {},
|
||||
"common:WindowZoomIn": {},
|
||||
"common:WindowZoomOut": {},
|
||||
"common:WindowZoomReset": {},
|
||||
"linux:ApplicationStartup": {},
|
||||
"linux:SystemThemeChanged": {},
|
||||
"linux:WindowDeleteEvent": {},
|
||||
"linux:WindowDidMove": {},
|
||||
"linux:WindowDidResize": {},
|
||||
"linux:WindowFocusIn": {},
|
||||
"linux:WindowFocusOut": {},
|
||||
"linux:WindowLoadStarted": {},
|
||||
"linux:WindowLoadRedirected": {},
|
||||
"linux:WindowLoadCommitted": {},
|
||||
"linux:WindowLoadFinished": {},
|
||||
"mac:ApplicationDidBecomeActive": {},
|
||||
"mac:ApplicationDidChangeBackingProperties": {},
|
||||
"mac:ApplicationDidChangeEffectiveAppearance": {},
|
||||
"mac:ApplicationDidChangeIcon": {},
|
||||
"mac:ApplicationDidChangeOcclusionState": {},
|
||||
"mac:ApplicationDidChangeScreenParameters": {},
|
||||
"mac:ApplicationDidChangeStatusBarFrame": {},
|
||||
"mac:ApplicationDidChangeStatusBarOrientation": {},
|
||||
"mac:ApplicationDidChangeTheme": {},
|
||||
"mac:ApplicationDidFinishLaunching": {},
|
||||
"mac:ApplicationDidHide": {},
|
||||
"mac:ApplicationDidResignActive": {},
|
||||
"mac:ApplicationDidUnhide": {},
|
||||
"mac:ApplicationDidUpdate": {},
|
||||
"mac:ApplicationShouldHandleReopen": {},
|
||||
"mac:ApplicationWillBecomeActive": {},
|
||||
"mac:ApplicationWillFinishLaunching": {},
|
||||
"mac:ApplicationWillHide": {},
|
||||
"mac:ApplicationWillResignActive": {},
|
||||
"mac:ApplicationWillTerminate": {},
|
||||
"mac:ApplicationWillUnhide": {},
|
||||
"mac:ApplicationWillUpdate": {},
|
||||
"mac:MenuDidAddItem": {},
|
||||
"mac:MenuDidBeginTracking": {},
|
||||
"mac:MenuDidClose": {},
|
||||
"mac:MenuDidDisplayItem": {},
|
||||
"mac:MenuDidEndTracking": {},
|
||||
"mac:MenuDidHighlightItem": {},
|
||||
"mac:MenuDidOpen": {},
|
||||
"mac:MenuDidPopUp": {},
|
||||
"mac:MenuDidRemoveItem": {},
|
||||
"mac:MenuDidSendAction": {},
|
||||
"mac:MenuDidSendActionToItem": {},
|
||||
"mac:MenuDidUpdate": {},
|
||||
"mac:MenuWillAddItem": {},
|
||||
"mac:MenuWillBeginTracking": {},
|
||||
"mac:MenuWillDisplayItem": {},
|
||||
"mac:MenuWillEndTracking": {},
|
||||
"mac:MenuWillHighlightItem": {},
|
||||
"mac:MenuWillOpen": {},
|
||||
"mac:MenuWillPopUp": {},
|
||||
"mac:MenuWillRemoveItem": {},
|
||||
"mac:MenuWillSendAction": {},
|
||||
"mac:MenuWillSendActionToItem": {},
|
||||
"mac:MenuWillUpdate": {},
|
||||
"mac:WebViewDidCommitNavigation": {},
|
||||
"mac:WebViewDidFinishNavigation": {},
|
||||
"mac:WebViewDidReceiveServerRedirectForProvisionalNavigation": {},
|
||||
"mac:WebViewDidStartProvisionalNavigation": {},
|
||||
"mac:WindowDidBecomeKey": {},
|
||||
"mac:WindowDidBecomeMain": {},
|
||||
"mac:WindowDidBeginSheet": {},
|
||||
"mac:WindowDidChangeAlpha": {},
|
||||
"mac:WindowDidChangeBackingLocation": {},
|
||||
"mac:WindowDidChangeBackingProperties": {},
|
||||
"mac:WindowDidChangeCollectionBehavior": {},
|
||||
"mac:WindowDidChangeEffectiveAppearance": {},
|
||||
"mac:WindowDidChangeOcclusionState": {},
|
||||
"mac:WindowDidChangeOrderingMode": {},
|
||||
"mac:WindowDidChangeScreen": {},
|
||||
"mac:WindowDidChangeScreenParameters": {},
|
||||
"mac:WindowDidChangeScreenProfile": {},
|
||||
"mac:WindowDidChangeScreenSpace": {},
|
||||
"mac:WindowDidChangeScreenSpaceProperties": {},
|
||||
"mac:WindowDidChangeSharingType": {},
|
||||
"mac:WindowDidChangeSpace": {},
|
||||
"mac:WindowDidChangeSpaceOrderingMode": {},
|
||||
"mac:WindowDidChangeTitle": {},
|
||||
"mac:WindowDidChangeToolbar": {},
|
||||
"mac:WindowDidDeminiaturize": {},
|
||||
"mac:WindowDidEndSheet": {},
|
||||
"mac:WindowDidEnterFullScreen": {},
|
||||
"mac:WindowDidEnterVersionBrowser": {},
|
||||
"mac:WindowDidExitFullScreen": {},
|
||||
"mac:WindowDidExitVersionBrowser": {},
|
||||
"mac:WindowDidExpose": {},
|
||||
"mac:WindowDidFocus": {},
|
||||
"mac:WindowDidMiniaturize": {},
|
||||
"mac:WindowDidMove": {},
|
||||
"mac:WindowDidOrderOffScreen": {},
|
||||
"mac:WindowDidOrderOnScreen": {},
|
||||
"mac:WindowDidResignKey": {},
|
||||
"mac:WindowDidResignMain": {},
|
||||
"mac:WindowDidResize": {},
|
||||
"mac:WindowDidUpdate": {},
|
||||
"mac:WindowDidUpdateAlpha": {},
|
||||
"mac:WindowDidUpdateCollectionBehavior": {},
|
||||
"mac:WindowDidUpdateCollectionProperties": {},
|
||||
"mac:WindowDidUpdateShadow": {},
|
||||
"mac:WindowDidUpdateTitle": {},
|
||||
"mac:WindowDidUpdateToolbar": {},
|
||||
"mac:WindowDidZoom": {},
|
||||
"mac:WindowFileDraggingEntered": {},
|
||||
"mac:WindowFileDraggingExited": {},
|
||||
"mac:WindowFileDraggingPerformed": {},
|
||||
"mac:WindowHide": {},
|
||||
"mac:WindowMaximise": {},
|
||||
"mac:WindowUnMaximise": {},
|
||||
"mac:WindowMinimise": {},
|
||||
"mac:WindowUnMinimise": {},
|
||||
"mac:WindowShouldClose": {},
|
||||
"mac:WindowShow": {},
|
||||
"mac:WindowWillBecomeKey": {},
|
||||
"mac:WindowWillBecomeMain": {},
|
||||
"mac:WindowWillBeginSheet": {},
|
||||
"mac:WindowWillChangeOrderingMode": {},
|
||||
"mac:WindowWillClose": {},
|
||||
"mac:WindowWillDeminiaturize": {},
|
||||
"mac:WindowWillEnterFullScreen": {},
|
||||
"mac:WindowWillEnterVersionBrowser": {},
|
||||
"mac:WindowWillExitFullScreen": {},
|
||||
"mac:WindowWillExitVersionBrowser": {},
|
||||
"mac:WindowWillFocus": {},
|
||||
"mac:WindowWillMiniaturize": {},
|
||||
"mac:WindowWillMove": {},
|
||||
"mac:WindowWillOrderOffScreen": {},
|
||||
"mac:WindowWillOrderOnScreen": {},
|
||||
"mac:WindowWillResignMain": {},
|
||||
"mac:WindowWillResize": {},
|
||||
"mac:WindowWillUnfocus": {},
|
||||
"mac:WindowWillUpdate": {},
|
||||
"mac:WindowWillUpdateAlpha": {},
|
||||
"mac:WindowWillUpdateCollectionBehavior": {},
|
||||
"mac:WindowWillUpdateCollectionProperties": {},
|
||||
"mac:WindowWillUpdateShadow": {},
|
||||
"mac:WindowWillUpdateTitle": {},
|
||||
"mac:WindowWillUpdateToolbar": {},
|
||||
"mac:WindowWillUpdateVisibility": {},
|
||||
"mac:WindowWillUseStandardFrame": {},
|
||||
"mac:WindowZoomIn": {},
|
||||
"mac:WindowZoomOut": {},
|
||||
"mac:WindowZoomReset": {},
|
||||
"windows:APMPowerSettingChange": {},
|
||||
"windows:APMPowerStatusChange": {},
|
||||
"windows:APMResumeAutomatic": {},
|
||||
"windows:APMResumeSuspend": {},
|
||||
"windows:APMSuspend": {},
|
||||
"windows:ApplicationStarted": {},
|
||||
"windows:SystemThemeChanged": {},
|
||||
"windows:WebViewNavigationCompleted": {},
|
||||
"windows:WindowActive": {},
|
||||
"windows:WindowBackgroundErase": {},
|
||||
"windows:WindowClickActive": {},
|
||||
"windows:WindowClosing": {},
|
||||
"windows:WindowDidMove": {},
|
||||
"windows:WindowDidResize": {},
|
||||
"windows:WindowDPIChanged": {},
|
||||
"windows:WindowDragDrop": {},
|
||||
"windows:WindowDragEnter": {},
|
||||
"windows:WindowDragLeave": {},
|
||||
"windows:WindowDragOver": {},
|
||||
"windows:WindowEndMove": {},
|
||||
"windows:WindowEndResize": {},
|
||||
"windows:WindowFullscreen": {},
|
||||
"windows:WindowHide": {},
|
||||
"windows:WindowInactive": {},
|
||||
"windows:WindowKeyDown": {},
|
||||
"windows:WindowKeyUp": {},
|
||||
"windows:WindowKillFocus": {},
|
||||
"windows:WindowNonClientHit": {},
|
||||
"windows:WindowNonClientMouseDown": {},
|
||||
"windows:WindowNonClientMouseLeave": {},
|
||||
"windows:WindowNonClientMouseMove": {},
|
||||
"windows:WindowNonClientMouseUp": {},
|
||||
"windows:WindowPaint": {},
|
||||
"windows:WindowRestore": {},
|
||||
"windows:WindowSetFocus": {},
|
||||
"windows:WindowShow": {},
|
||||
"windows:WindowStartMove": {},
|
||||
"windows:WindowStartResize": {},
|
||||
"windows:WindowUnFullscreen": {},
|
||||
"windows:WindowZOrderChanged": {},
|
||||
"windows:WindowMinimise": {},
|
||||
"windows:WindowUnMinimise": {},
|
||||
"windows:WindowMaximise": {},
|
||||
"windows:WindowUnMaximise": {},
|
||||
"mac:WebViewDidStartProvisionalNavigation": {},
|
||||
"mac:WindowDidBecomeKey": {},
|
||||
"mac:WindowDidBecomeMain": {},
|
||||
"mac:WindowDidBeginSheet": {},
|
||||
"mac:WindowDidChangeAlpha": {},
|
||||
"mac:WindowDidChangeBackingLocation": {},
|
||||
"mac:WindowDidChangeBackingProperties": {},
|
||||
"mac:WindowDidChangeCollectionBehavior": {},
|
||||
"mac:WindowDidChangeEffectiveAppearance": {},
|
||||
"mac:WindowDidChangeOcclusionState": {},
|
||||
"mac:WindowDidChangeOrderingMode": {},
|
||||
"mac:WindowDidChangeScreen": {},
|
||||
"mac:WindowDidChangeScreenParameters": {},
|
||||
"mac:WindowDidChangeScreenProfile": {},
|
||||
"mac:WindowDidChangeScreenSpace": {},
|
||||
"mac:WindowDidChangeScreenSpaceProperties": {},
|
||||
"mac:WindowDidChangeSharingType": {},
|
||||
"mac:WindowDidChangeSpace": {},
|
||||
"mac:WindowDidChangeSpaceOrderingMode": {},
|
||||
"mac:WindowDidChangeTitle": {},
|
||||
"mac:WindowDidChangeToolbar": {},
|
||||
"mac:WindowDidDeminiaturize": {},
|
||||
"mac:WindowDidEndSheet": {},
|
||||
"mac:WindowDidEnterFullScreen": {},
|
||||
"mac:WindowDidEnterVersionBrowser": {},
|
||||
"mac:WindowDidExitFullScreen": {},
|
||||
"mac:WindowDidExitVersionBrowser": {},
|
||||
"mac:WindowDidExpose": {},
|
||||
"mac:WindowDidFocus": {},
|
||||
"mac:WindowDidMiniaturize": {},
|
||||
"mac:WindowDidMove": {},
|
||||
"mac:WindowDidOrderOffScreen": {},
|
||||
"mac:WindowDidOrderOnScreen": {},
|
||||
"mac:WindowDidResignKey": {},
|
||||
"mac:WindowDidResignMain": {},
|
||||
"mac:WindowDidResize": {},
|
||||
"mac:WindowDidUpdate": {},
|
||||
"mac:WindowDidUpdateAlpha": {},
|
||||
"mac:WindowDidUpdateCollectionBehavior": {},
|
||||
"mac:WindowDidUpdateCollectionProperties": {},
|
||||
"mac:WindowDidUpdateShadow": {},
|
||||
"mac:WindowDidUpdateTitle": {},
|
||||
"mac:WindowDidUpdateToolbar": {},
|
||||
"mac:WindowDidZoom": {},
|
||||
"mac:WindowFileDraggingEntered": {},
|
||||
"mac:WindowFileDraggingExited": {},
|
||||
"mac:WindowFileDraggingPerformed": {},
|
||||
"mac:WindowHide": {},
|
||||
"mac:WindowMaximise": {},
|
||||
"mac:WindowUnMaximise": {},
|
||||
"mac:WindowMinimise": {},
|
||||
"mac:WindowUnMinimise": {},
|
||||
"mac:WindowShouldClose": {},
|
||||
"mac:WindowShow": {},
|
||||
"mac:WindowWillBecomeKey": {},
|
||||
"mac:WindowWillBecomeMain": {},
|
||||
"mac:WindowWillBeginSheet": {},
|
||||
"mac:WindowWillChangeOrderingMode": {},
|
||||
"mac:WindowWillClose": {},
|
||||
"mac:WindowWillDeminiaturize": {},
|
||||
"mac:WindowWillEnterFullScreen": {},
|
||||
"mac:WindowWillEnterVersionBrowser": {},
|
||||
"mac:WindowWillExitFullScreen": {},
|
||||
"mac:WindowWillExitVersionBrowser": {},
|
||||
"mac:WindowWillFocus": {},
|
||||
"mac:WindowWillMiniaturize": {},
|
||||
"mac:WindowWillMove": {},
|
||||
"mac:WindowWillOrderOffScreen": {},
|
||||
"mac:WindowWillOrderOnScreen": {},
|
||||
"mac:WindowWillResignMain": {},
|
||||
"mac:WindowWillResize": {},
|
||||
"mac:WindowWillUnfocus": {},
|
||||
"mac:WindowWillUpdate": {},
|
||||
"mac:WindowWillUpdateAlpha": {},
|
||||
"mac:WindowWillUpdateCollectionBehavior": {},
|
||||
"mac:WindowWillUpdateCollectionProperties": {},
|
||||
"mac:WindowWillUpdateShadow": {},
|
||||
"mac:WindowWillUpdateTitle": {},
|
||||
"mac:WindowWillUpdateToolbar": {},
|
||||
"mac:WindowWillUpdateVisibility": {},
|
||||
"mac:WindowWillUseStandardFrame": {},
|
||||
"mac:WindowZoomIn": {},
|
||||
"mac:WindowZoomOut": {},
|
||||
"mac:WindowZoomReset": {},
|
||||
"windows:APMPowerSettingChange": {},
|
||||
"windows:APMPowerStatusChange": {},
|
||||
"windows:APMResumeAutomatic": {},
|
||||
"windows:APMResumeSuspend": {},
|
||||
"windows:APMSuspend": {},
|
||||
"windows:ApplicationStarted": {},
|
||||
"windows:SystemThemeChanged": {},
|
||||
"windows:WebViewNavigationCompleted": {},
|
||||
"windows:WindowActive": {},
|
||||
"windows:WindowBackgroundErase": {},
|
||||
"windows:WindowClickActive": {},
|
||||
"windows:WindowClosing": {},
|
||||
"windows:WindowDidMove": {},
|
||||
"windows:WindowDidResize": {},
|
||||
"windows:WindowDPIChanged": {},
|
||||
"windows:WindowDragDrop": {},
|
||||
"windows:WindowDragEnter": {},
|
||||
"windows:WindowDragLeave": {},
|
||||
"windows:WindowDragOver": {},
|
||||
"windows:WindowEndMove": {},
|
||||
"windows:WindowEndResize": {},
|
||||
"windows:WindowFullscreen": {},
|
||||
"windows:WindowHide": {},
|
||||
"windows:WindowInactive": {},
|
||||
"windows:WindowKeyDown": {},
|
||||
"windows:WindowKeyUp": {},
|
||||
"windows:WindowKillFocus": {},
|
||||
"windows:WindowNonClientHit": {},
|
||||
"windows:WindowNonClientMouseDown": {},
|
||||
"windows:WindowNonClientMouseLeave": {},
|
||||
"windows:WindowNonClientMouseMove": {},
|
||||
"windows:WindowNonClientMouseUp": {},
|
||||
"windows:WindowPaint": {},
|
||||
"windows:WindowRestore": {},
|
||||
"windows:WindowSetFocus": {},
|
||||
"windows:WindowShow": {},
|
||||
"windows:WindowStartMove": {},
|
||||
"windows:WindowStartResize": {},
|
||||
"windows:WindowUnFullscreen": {},
|
||||
"windows:WindowZOrderChanged": {},
|
||||
"windows:WindowMinimise": {},
|
||||
"windows:WindowUnMinimise": {},
|
||||
"windows:WindowMaximise": {},
|
||||
"windows:WindowUnMaximise": {},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue