Using DearpyGUI, I'm trying to add some drag and drop functionality.
I tried to attach parent and also child components, it is still not working and the "d.pending_events" is printing 0 even if I drag and drop an image or file.
this is the output when I run the script
(env_312) (base) xam a@xam-58:~/Desktop/Python/310py$ python test1.py ✅ Found Parent window: 0x800df0 🔎 Dumping window tree: ↳ 0x800df0 name: Drag-and-Drop-Example ↳ 0x800df1 name: None ↳ 0x2a00009 name: Drag-and-Drop-Example Child: 0x2a00009, name: Drag-and-Drop-Example
import dearpygui.dearpygui as dpg
import threading
import time from Xlib
import X, display, Xatom
#PARENT
def _func_find_window_by_name(name, d):
# d = display.Display()
root = d.screen().root
def search(w):
for child in w.query_tree().children:
try:
win_name = child.get_wm_name()
if win_name and name in win_name:
return child
result = search(child)
if result:
return result
except:
pass
return None
return search(root)
#CHILDREN
def find_real_content_window(parent):
for child in parent.query_tree().children:
name = child.get_wm_name()
if name:
print(f"Child: {hex(child.id)}, name: {name}")
if name and "Drag-and-Drop-Example" in name:
# print(f"Found content window: {hex(child.id)}")
return child
return parent # fallback
def _func_setup_xdnd(win, d):
XdndAware = d.intern_atom("XdndAware")
win.change_property(XdndAware, Xatom.ATOM, 32, [5])
d.flush()
# Verify
prop = win.get_full_property(XdndAware, Xatom.ATOM)
if prop:
print(f"✅ XdndAware property set correctly: {prop.value}")
print(f"✅ Using child content window: {hex(win.id)}")
else:
print("❌ Failed to set XdndAware property.")
def _func_xdnd_loop(win, d):
XdndEnter = d.intern_atom("XdndEnter")
XdndPosition = d.intern_atom("XdndPosition")
XdndDrop = d.intern_atom("XdndDrop")
XdndSelection = d.intern_atom("XdndSelection")
UTF8_STRING = d.intern_atom("UTF8_STRING")
print(f"👂 Listening for XDND events on: {hex(win.id)}")
while True:
print(d.pending_events())
if d.pending_events():
print("🔄 Processing pending events...")
# # e = d.next_event()
# # if e.type == X.ClientMessage:
# # if e.client_type == XdndEnter:
# # print("📥 Drag entered")
# # elif e.client_type == XdndPosition:
# # print("📍 Drag position updated")
# # elif e.client_type == XdndDrop:
# # print("📦 Drop detected!")
# # # Ask for the selection contents
# # win.convert_selection(XdndSelection, UTF8_STRING, X.CurrentTime)
# # elif e.type == X.SelectionNotify:
# # prop = win.get_full_property(e.property, 0)
# # if prop:
# # uris = prop.value.decode("utf-8").strip().splitlines()
# # for uri in uris:
# # if uri.startswith("file://"):
# # path = uri[7:] # strip file://
# # print(f"📄 Dropped file: {path}")
# # # TODO: update DPG UI here if you want
else:
time.sleep(0.01)
def dump_tree(w, level=0):
indent = " " * level
name = w.get_wm_name()
print(f"{indent}↳ {hex(w.id)} name: {name}")
for child in w.query_tree().children:
dump_tree(child, level+1)
dpg.create_context() dpg.create_viewport(title='Drag-and-Drop-Example', width=400, height=300)
with dpg.window(label="main-window", tag="main-window", no_close=True):
dpg.add_text("🗂 Drag a file from Nautilus here!")
dpg.setup_dearpygui() dpg.show_viewport()
time.sleep(2)
# dpg.set_primary_window("main-window", True)
d = display.Display() win =
_func_find_window_by_name("Drag-and-Drop-Example", d) if not win:
raise Exception("Could not find DPG window") print(f"✅ Found Parent window: {hex(win.id)}")
print("🔎 Dumping window tree:") dump_tree(win)
win = find_real_content_window(win)
_func_setup_xdnd(win, d)
threading.Thread(target=_func_xdnd_loop, args=(win, d), daemon=True).start()
while dpg.is_dearpygui_running():
dpg.render_dearpygui_frame()
dpg.destroy_context()
I already fix it by adding this line inside "xdnd_event_loop" function.
# THIS IS CRUCIAL:
win.change_attributes(event_mask=X.PropertyChangeMask | X.StructureNotifyMask | X.SubstructureNotifyMask)
d.flush()
while True:
while d.pending_events():