diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 9d9368d8b8..99f7f2b078 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -3086,7 +3086,7 @@ Window (Windows only) Snap the player window to screen edges. ``--drag-and-drop=`` - (X11 and Wayland only) + (X11, Wayland and Windows only) Controls the default behavior of drag and drop on platforms that support this. ``auto`` will obey what the underlying os/platform gives mpv. Typically, holding shift during the drag and drop will append the item to the playlist. Otherwise, diff --git a/video/out/w32_common.c b/video/out/w32_common.c index 8a7c157952..07ae957be7 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -1594,7 +1594,7 @@ static void *gui_thread(void *ptr) if (SUCCEEDED(OleInitialize(NULL))) { ole_ok = true; - IDropTarget *dt = mp_w32_droptarget_create(w32->log, w32->input_ctx); + IDropTarget *dt = mp_w32_droptarget_create(w32->log, w32->opts, w32->input_ctx); RegisterDragDrop(w32->window, dt); // ITaskbarList2 has the MarkFullscreenWindow method, which is used to diff --git a/video/out/win32/droptarget.c b/video/out/win32/droptarget.c index 70400352b3..3443f2eaba 100644 --- a/video/out/win32/droptarget.c +++ b/video/out/win32/droptarget.c @@ -35,6 +35,7 @@ struct droptarget { atomic_int ref_cnt; struct mp_log *log; struct input_ctx *input_ctx; + struct mp_vo_opts *opts; DWORD last_effect; IDataObject *data_obj; }; @@ -129,12 +130,20 @@ static STDMETHODIMP DropTarget_Drop(IDropTarget *self, IDataObject *pDataObj, DWORD *pdwEffect) { struct droptarget *t = (struct droptarget *)self; - enum mp_dnd_action action = (grfKeyState & MK_SHIFT) ? DND_APPEND : DND_REPLACE; + + enum mp_dnd_action action; + if (t->opts->drag_and_drop >= 0) { + action = t->opts->drag_and_drop; + } else { + action = (grfKeyState & MK_SHIFT) ? DND_APPEND : DND_REPLACE; + } SAFE_RELEASE(t->data_obj); STGMEDIUM medium; - if (SUCCEEDED(IDataObject_GetData(pDataObj, &fmtetc_file, &medium))) { + if (t->opts->drag_and_drop == -2) { + t->last_effect = DROPEFFECT_NONE; + } else if (SUCCEEDED(IDataObject_GetData(pDataObj, &fmtetc_file, &medium))) { if (GlobalLock(medium.hGlobal)) { HDROP drop = medium.hGlobal; @@ -200,6 +209,7 @@ static IDropTargetVtbl idroptarget_vtbl = { }; IDropTarget *mp_w32_droptarget_create(struct mp_log *log, + struct mp_vo_opts *opts, struct input_ctx *input_ctx) { fmtetc_url.cfFormat = RegisterClipboardFormatW(L"UniformResourceLocatorW"); @@ -210,6 +220,7 @@ IDropTarget *mp_w32_droptarget_create(struct mp_log *log, dt->last_effect = 0; dt->data_obj = NULL; dt->log = mp_log_new(dt, log, "droptarget"); + dt->opts = opts; dt->input_ctx = input_ctx; return &dt->iface; diff --git a/video/out/win32/droptarget.h b/video/out/win32/droptarget.h index 53eb5ac998..1c18c06d9b 100644 --- a/video/out/win32/droptarget.h +++ b/video/out/win32/droptarget.h @@ -25,9 +25,11 @@ #include "input/input.h" #include "common/msg.h" #include "common/common.h" +#include "options/options.h" // Create a IDropTarget implementation that sends dropped files to input_ctx IDropTarget *mp_w32_droptarget_create(struct mp_log *log, + struct mp_vo_opts *opts, struct input_ctx *input_ctx); #endif