input: add insert-next support for drag-and-drop

This commit adds a DND_INSERT_NEXT action option for drag-and-drop,
allows for selecting it through the --drag-and-drop=insert-next option,
and adds the necessary plumbing to make that happen when something is
dragged onto the player.
This commit is contained in:
David Vaughan
2024-02-03 19:41:43 -08:00
committed by Dudemanguy
parent 432256e5d2
commit a8a314b829
5 changed files with 37 additions and 12 deletions

View File

@@ -3197,13 +3197,14 @@ Window
``--snap-window`` ``--snap-window``
(Windows only) Snap the player window to screen edges. (Windows only) Snap the player window to screen edges.
``--drag-and-drop=<no|auto|replace|append>`` ``--drag-and-drop=<no|auto|replace|append|insert-next>``
Controls the default behavior of drag and drop on platforms that support this. Controls the default behavior of drag and drop on platforms that support
``auto`` will obey what the underlying os/platform gives mpv. Typically, holding this. ``auto`` will obey what the underlying os/platform gives mpv.
shift during the drag and drop will append the item to the playlist. Otherwise, Typically, holding shift during the drag and drop will append the item to
it will completely replace it. ``replace`` and ``append`` always force replacing the playlist. Otherwise, it will completely replace it. ``replace``,
and appending to the playlist respectively. ``no`` disables all drag and drop ``append``, and ``insert-next`` always force replacing, appending to, and
behavior. inserting next into the playlist respectively. ``no`` disables all drag and
drop behavior.
``--ontop`` ``--ontop``
Makes the player window stay on top of other windows. Makes the player window stay on top of other windows.

View File

@@ -37,6 +37,21 @@ void mp_event_drop_files(struct input_ctx *ictx, int num_files, char **files,
}; };
mp_input_run_cmd(ictx, cmd); mp_input_run_cmd(ictx, cmd);
} }
} else if (action == DND_INSERT_NEXT) {
/* To insert the entries in the correct order, we iterate over them
backwards */
for (int i = num_files - 1; i >= 0; i--) {
const char *cmd[] = {
"osd-auto",
"loadfile",
files[i],
/* Since we're inserting in reverse, wait til the final item
is added to start playing */
(i > 0) ? "insert-next" : "insert-next-play",
NULL
};
mp_input_run_cmd(ictx, cmd);
}
} else { } else {
for (int i = 0; i < num_files; i++) { for (int i = 0; i < num_files; i++) {
const char *cmd[] = { const char *cmd[] = {

View File

@@ -24,16 +24,17 @@ struct input_ctx;
enum mp_dnd_action { enum mp_dnd_action {
DND_REPLACE, DND_REPLACE,
DND_APPEND, DND_APPEND,
DND_INSERT_NEXT,
}; };
// Enqueue files for playback after drag and drop // Enqueue files for playback after drag and drop
void mp_event_drop_files(struct input_ctx *ictx, int num_files, char **files, void mp_event_drop_files(struct input_ctx *ictx, int num_files, char **files,
enum mp_dnd_action append); enum mp_dnd_action action);
// Drop data in a specific format (identified by the mimetype). // Drop data in a specific format (identified by the mimetype).
// Returns <0 on error, ==0 if data was ok but empty, >0 on success. // Returns <0 on error, ==0 if data was ok but empty, >0 on success.
int mp_event_drop_mime_data(struct input_ctx *ictx, const char *mime_type, int mp_event_drop_mime_data(struct input_ctx *ictx, const char *mime_type,
bstr data, enum mp_dnd_action append); bstr data, enum mp_dnd_action action);
// Many drag & drop APIs support multiple mime types, and this function returns // Many drag & drop APIs support multiple mime types, and this function returns
// whether a type is preferred (higher integer score), or supported (scores // whether a type is preferred (higher integer score), or supported (scores

View File

@@ -112,7 +112,9 @@ static const m_option_t mp_vo_opt_list[] = {
{"vo", OPT_SETTINGSLIST(video_driver_list, &vo_obj_list)}, {"vo", OPT_SETTINGSLIST(video_driver_list, &vo_obj_list)},
{"taskbar-progress", OPT_BOOL(taskbar_progress)}, {"taskbar-progress", OPT_BOOL(taskbar_progress)},
{"drag-and-drop", OPT_CHOICE(drag_and_drop, {"no", -2}, {"auto", -1}, {"drag-and-drop", OPT_CHOICE(drag_and_drop, {"no", -2}, {"auto", -1},
{"replace", DND_REPLACE}, {"append", DND_APPEND})}, {"replace", DND_REPLACE},
{"append", DND_APPEND},
{"insert-next", DND_INSERT_NEXT})},
{"snap-window", OPT_BOOL(snap_window)}, {"snap-window", OPT_BOOL(snap_window)},
{"ontop", OPT_BOOL(ontop)}, {"ontop", OPT_BOOL(ontop)},
{"ontop-level", OPT_CHOICE(ontop_level, {"window", -1}, {"system", -2}, {"ontop-level", OPT_CHOICE(ontop_level, {"window", -1}, {"system", -2},

View File

@@ -695,8 +695,14 @@ static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, u
wl->dnd_action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ? wl->dnd_action = dnd_action & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY ?
DND_REPLACE : DND_APPEND; DND_REPLACE : DND_APPEND;
} }
MP_VERBOSE(wl, "DND action is %s\n",
wl->dnd_action == DND_REPLACE ? "DND_REPLACE" : "DND_APPEND"); static const char * const dnd_action_names[] = {
[DND_REPLACE] = "DND_REPLACE",
[DND_APPEND] = "DND_APPEND",
[DND_INSERT_NEXT] = "DND_INSERT_NEXT",
};
MP_VERBOSE(wl, "DND action is %s\n", dnd_action_names[wl->dnd_action]);
} }
} }