Fix dnd kitten: restrict drop to boxes matching drag source allowed operations

Agent-Logs-Url: https://github.com/kovidgoyal/kitty/sessions/41b8254d-fc79-4f41-9775-67d1ddfceb5b

Co-authored-by: kovidgoyal <1308621+kovidgoyal@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-14 02:49:17 +00:00
committed by GitHub
parent bfc3646868
commit 66dca3cde1
6 changed files with 73 additions and 20 deletions

View File

@@ -379,14 +379,15 @@ func parse_uri_list(src string) (ans []string, err error) {
}
type drop_status struct {
offered_mimes []string
accepted_mimes []string
uri_list []string
cell_x, cell_y int
action int
in_window bool
reading_data bool
is_remote_client bool
offered_mimes []string
accepted_mimes []string
uri_list []string
cell_x, cell_y int
action int
in_window bool
reading_data bool
is_remote_client bool
source_allowed_ops int
dropping_to *dir_handle
root_remote_dir *remote_dir_entry
@@ -594,7 +595,7 @@ func (dnd *dnd) request_mime_data() {
var offered_mimes_buf strings.Builder
func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes string, is_drop bool) (needs_rerender bool) {
func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes string, is_drop bool, source_allowed_ops int) (needs_rerender bool) {
prev_status := dnd.drop_status
dnd.drop_status.cell_x, dnd.drop_status.cell_y = cell_x, cell_y
if offered_mimes != "" {
@@ -614,6 +615,9 @@ func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes st
}
}
offered_mimes_buf.Reset()
if source_allowed_ops != 0 {
dnd.drop_status.source_allowed_ops = source_allowed_ops
}
if dnd.copy_button_region.has(cell_x, cell_y) {
dnd.drop_status.action = copy_on_drop
} else if dnd.move_button_region.has(cell_x, cell_y) {
@@ -629,6 +633,13 @@ func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes st
dnd.drop_status.action = move_on_drop
}
}
// Restrict to operations allowed by the drag source.
if sao := dnd.drop_status.source_allowed_ops; sao != 0 && dnd.drop_status.action != 0 {
if sao&dnd.drop_status.action == 0 {
dnd.drop_status.action = 0
dnd.drop_status.accepted_mimes = nil
}
}
dnd.drop_status.in_window = cell_x > -1 && cell_y > -1
if !dnd.drop_status.in_window || dnd.drag_status.active { // disallow self drag and drop
dnd.reset_drop()

View File

@@ -259,11 +259,11 @@ func (dnd *dnd) run_loop() (err error) {
if cmd.Payload != nil {
payload = utils.UnsafeBytesToString(cmd.Payload)
}
if dnd.on_drop_move(cmd.X, cmd.Y, cmd.Has_more, payload, false) {
if dnd.on_drop_move(cmd.X, cmd.Y, cmd.Has_more, payload, false, cmd.Operation) {
dnd.render_screen()
}
case 'M':
if dnd.on_drop_move(cmd.X, cmd.Y, cmd.Has_more, utils.UnsafeBytesToString(cmd.Payload), true) {
if dnd.on_drop_move(cmd.X, cmd.Y, cmd.Has_more, utils.UnsafeBytesToString(cmd.Payload), true, cmd.Operation) {
dnd.render_screen()
}
case 'R':