diff --git a/src/app.rs b/src/app.rs index 1dbf6e6..c742244 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6807,25 +6807,44 @@ impl Application for App { // Yoda phase 3: Dolphin-style quick actions toolbar. Items are // rendered from self.config.toolbar (Vec) — the user - // picks the set AND the order via drag-drop in Settings. Dispatch - // goes through Action::message so keybinding and toolbar share the - // same code path. + // picks the set AND the order via direct drag-drop on the toolbar. + // Short click = action (shared Action::message dispatch); drag past + // the default 8px threshold = reorder (ToolbarReorder message). if !self.config.toolbar.is_empty() { + use cosmic::iced::clipboard::dnd::DndAction as DndAct; let clipboard_has = self.clipboard_has_content(); let buttons: Vec> = self .config .toolbar .iter() .map(|a| { - let (icon, label, msg) = toolbar_action_ui(*a); - let enabled = !matches!(a, ToolbarAction::Paste) || clipboard_has; + let action = *a; + let (icon, label, msg) = toolbar_action_ui(action); + let enabled = !matches!(action, ToolbarAction::Paste) || clipboard_has; let btn = widget::button::icon(widget::icon::from_name(icon).size(16)); let btn = if enabled { btn.on_press(msg) } else { btn }; - widget::tooltip( + let tooltip = widget::tooltip( btn, widget::text::body(label), widget::tooltip::Position::Bottom, + ); + let source = widget::dnd_source::(tooltip) + .drag_content(move || ToolbarActionPayload(action.to_u8())); + widget::dnd_destination( + source, + vec![std::borrow::Cow::Borrowed(TOOLBAR_MIME)], ) + .data_received_for::( + move |payload: Option| { + match payload.and_then(|p| ToolbarAction::from_u8(p.0)) { + Some(src) if src != action => { + Message::ToolbarReorder { src, target: action } + } + _ => Message::ToolbarReorder { src: action, target: action }, + } + }, + ) + .action(DndAct::Move) .into() }) .collect();