Drag and drop performance issue on more complex html pages.
Specification
- pywebview version: 5.1
- operating system: Windows
- web renderer: Default
Description
When a window contains too many elements, the drag and drop performace suffers greatly. It can take over 5 seconds to finally register a drop has occured.
For example in the following code, dropping is nearly instant, but change the rendered html to google.com for example, then after 10 seconds, the drop is finally registered:
from webview.dom import DOMEventHandler
import datetime
def on_drag(e):
print(f"on_drag {datetime.datetime.now()}")
pass
def on_drop(e):
print(f"on_drop {datetime.datetime.now()}")
files = e['dataTransfer']['files']
if len(files) == 0:
return
print(f'Event: {e["type"]}. Dropped files:')
for file in files:
print(file.get('pywebviewFullPath'))
def bind(window):
window.dom.document.events.dragenter += DOMEventHandler(on_drag, True, True)
window.dom.document.events.dragstart += DOMEventHandler(on_drag, True, True)
window.dom.document.events.dragover += DOMEventHandler(on_drag, True, True)
window.dom.document.events.drop += DOMEventHandler(on_drop, True, True)
if __name__ == '__main__':
window = webview.create_window(
'Drag & drop example', html='''
<html>
<body style="height: 100vh;">
<h1>Drag files here</h1>
<div class="pywebview-drag-region">Drop zone</div>
</body>
</html>
'''
)
webview.start(bind, window)
Practicalities
-
YES I am willing to work on this issue myself. (If I know what to fix)
-
NO I am prepared to support this issue financially.
The logic for DOM events handling can be found in https://github.com/r0x0r/pywebview/blob/b1c0c1d6f225d31d4aeeabfde7a1682d1ee5b165/webview/util.py#L243
It launches a new thread for each event. This might be a reason for a lag.
The logic for DOM events handling can be found in
https://github.com/r0x0r/pywebview/blob/b1c0c1d6f225d31d4aeeabfde7a1682d1ee5b165/webview/util.py#L243
It launches a new thread for each event. This might be a reason for a lag.
The issue is with these three lines:
window.dom.document.events.dragenter += DOMEventHandler(on_drag, True, True)
window.dom.document.events.dragstart += DOMEventHandler(on_drag, True, True)
window.dom.document.events.dragover += DOMEventHandler(on_drag, True, True)
What handles the dragging functionality here?
The logic for DOM events handling can be found in https://github.com/r0x0r/pywebview/blob/b1c0c1d6f225d31d4aeeabfde7a1682d1ee5b165/webview/util.py#L243
It launches a new thread for each event. This might be a reason for a lag.
The issue is with these three lines:
window.dom.document.events.dragenter += DOMEventHandler(on_drag, True, True) window.dom.document.events.dragstart += DOMEventHandler(on_drag, True, True) window.dom.document.events.dragover += DOMEventHandler(on_drag, True, True)What handles the dragging functionality here?
The reason is that the dragoover event is triggered too frequently, which is equivalent to constantly triggering when you drag and drop a file into it
I have tested dragging a file, and I triggered it 30 times here
Perhaps the one below is what you want
get full file path html
<div id="drag_zone"></div>
onMounted(() => {
const element = document.getElementById('drag_zone');
if (!element) return;
element.addEventListener('dragover', (e) => {
e.preventDefault();
});
});
python
def on_drop(e):
files = e['dataTransfer']['files']
if len(files) == 0:
return
for file in files:
print(file.get('pywebviewFullPath'))
drag_zone = window.dom.get_element('#drag_zone')
event = 'drop'
setattr(drag_zone.events, event, DOMEvent(event, drag_zone._window, drag_zone))
drag_zone.events.drop += DOMEventHandler(on_drop, True, True)
import webview
from webview.dom import DOMEventHandler
import datetime
def on_drag(e):
print(f"on_drag {datetime.datetime.now()}")
pass
def on_drop(e):
print(f"on_drop {datetime.datetime.now()}")
files = e['dataTransfer']['files']
if len(files) == 0:
return
print(f'Event: {e["type"]}. Dropped files:')
for file in files:
print(file.get('pywebviewFullPath'))
def bind(window):
window.dom.document.events.drop += DOMEventHandler(on_drop, True, True)
if __name__ == '__main__':
window = webview.create_window(
'Drag & drop example', html='''
<html>
<body style="height: 100vh;">
<h1>Drag files here</h1>
<div class="pywebview-drag-region">Drop zone</div>
<script>
document.addEventListener('dragover', function(event) {
event.preventDefault();
});
</script>
</body>
</html>
'''
)
webview.start(bind, window)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
The message to post on the issue when closing it. If none provided, will not comment when closing an issue.