Skip to content

Commit 6071c7c

Browse files
committed
Merge pull request godotengine#97250 from Garetonchick/windows-drag-and-drop-fix
Windows: Fix dragging and dropping files from compressed files into editor
2 parents 2ad452a + 2bd7599 commit 6071c7c

File tree

5 files changed

+489
-31
lines changed

5 files changed

+489
-31
lines changed

platform/windows/SCsub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ common_win = [
2424
"gl_manager_windows_angle.cpp",
2525
"wgl_detect_version.cpp",
2626
"rendering_context_driver_vulkan_windows.cpp",
27+
"drop_target_windows.cpp",
2728
]
2829

2930
if env.msvc:

platform/windows/display_server_windows.cpp

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "display_server_windows.h"
3232

33+
#include "drop_target_windows.h"
3334
#include "os_windows.h"
3435
#include "wgl_detect_version.h"
3536

@@ -1617,11 +1618,17 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
16171618
}
16181619
#endif
16191620

1620-
if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
1621-
wintab_WTClose(windows[p_window].wtctx);
1622-
windows[p_window].wtctx = nullptr;
1621+
if ((tablet_get_current_driver() == "wintab") && wintab_available && wd.wtctx) {
1622+
wintab_WTClose(wd.wtctx);
1623+
wd.wtctx = nullptr;
1624+
}
1625+
1626+
if (wd.drop_target != nullptr) {
1627+
RevokeDragDrop(wd.hWnd);
1628+
wd.drop_target->Release();
16231629
}
1624-
DestroyWindow(windows[p_window].hWnd);
1630+
1631+
DestroyWindow(wd.hWnd);
16251632
windows.erase(p_window);
16261633

16271634
if (last_focused_window == p_window) {
@@ -1731,7 +1738,14 @@ void DisplayServerWindows::window_set_drop_files_callback(const Callable &p_call
17311738
_THREAD_SAFE_METHOD_
17321739

17331740
ERR_FAIL_COND(!windows.has(p_window));
1734-
windows[p_window].drop_files_callback = p_callable;
1741+
WindowData &window_data = windows[p_window];
1742+
1743+
window_data.drop_files_callback = p_callable;
1744+
1745+
if (window_data.drop_target == nullptr) {
1746+
window_data.drop_target = memnew(DropTargetWindows(&window_data));
1747+
ERR_FAIL_COND(RegisterDragDrop(window_data.hWnd, window_data.drop_target) != S_OK);
1748+
}
17351749
}
17361750

17371751
void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_window) {
@@ -5320,32 +5334,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
53205334
}
53215335
}
53225336
} break;
5323-
case WM_DROPFILES: {
5324-
HDROP hDropInfo = (HDROP)wParam;
5325-
const int buffsize = 4096;
5326-
WCHAR buf[buffsize];
5327-
5328-
int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF, nullptr, 0);
5329-
5330-
Vector<String> files;
5331-
5332-
for (int i = 0; i < fcount; i++) {
5333-
DragQueryFileW(hDropInfo, i, buf, buffsize);
5334-
String file = String::utf16((const char16_t *)buf);
5335-
files.push_back(file);
5336-
}
5337-
5338-
if (files.size() && windows[window_id].drop_files_callback.is_valid()) {
5339-
Variant v_files = files;
5340-
const Variant *v_args[1] = { &v_files };
5341-
Variant ret;
5342-
Callable::CallError ce;
5343-
windows[window_id].drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce);
5344-
if (ce.error != Callable::CallError::CALL_OK) {
5345-
ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(windows[window_id].drop_files_callback, v_args, 1, ce)));
5346-
}
5347-
}
5348-
} break;
53495337
default: {
53505338
if (user_proc) {
53515339
return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
@@ -6174,6 +6162,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
61746162
FreeLibrary(comctl32);
61756163
}
61766164

6165+
OleInitialize(nullptr);
6166+
61776167
memset(&wc, 0, sizeof(WNDCLASSEXW));
61786168
wc.cbSize = sizeof(WNDCLASSEXW);
61796169
wc.style = CS_OWNDC | CS_DBLCLKS;
@@ -6606,6 +6596,12 @@ DisplayServerWindows::~DisplayServerWindows() {
66066596
wintab_WTClose(windows[MAIN_WINDOW_ID].wtctx);
66076597
windows[MAIN_WINDOW_ID].wtctx = nullptr;
66086598
}
6599+
6600+
if (windows[MAIN_WINDOW_ID].drop_target != nullptr) {
6601+
RevokeDragDrop(windows[MAIN_WINDOW_ID].hWnd);
6602+
windows[MAIN_WINDOW_ID].drop_target->Release();
6603+
}
6604+
66096605
DestroyWindow(windows[MAIN_WINDOW_ID].hWnd);
66106606
}
66116607

@@ -6637,4 +6633,6 @@ DisplayServerWindows::~DisplayServerWindows() {
66376633
if (tts) {
66386634
memdelete(tts);
66396635
}
6636+
6637+
OleUninitialize();
66406638
}

platform/windows/display_server_windows.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,13 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
357357
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2,
358358
} SHC_PROCESS_DPI_AWARENESS;
359359

360+
class DropTargetWindows;
361+
360362
class DisplayServerWindows : public DisplayServer {
361363
// No need to register with GDCLASS, it's platform-specific and nothing is added.
362364

365+
friend class DropTargetWindows;
366+
363367
_THREAD_SAFE_CLASS_
364368

365369
// UXTheme API
@@ -521,6 +525,9 @@ class DisplayServerWindows : public DisplayServer {
521525
Callable input_text_callback;
522526
Callable drop_files_callback;
523527

528+
// OLE API
529+
DropTargetWindows *drop_target = nullptr;
530+
524531
WindowID transient_parent = INVALID_WINDOW_ID;
525532
HashSet<WindowID> transient_children;
526533

0 commit comments

Comments
 (0)