From 97324cd852f85d79ce65a984ebb9d99f71088069 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 10 Jun 2026 22:32:39 -0700 Subject: [PATCH] Fix the Gradient tool breaking the layer deletion hotkey (#4224) * Fix the Gradient tool breaking the layer deletion hotkey * Fix --- .../tool/tool_messages/gradient_tool.rs | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/editor/src/messages/tool/tool_messages/gradient_tool.rs b/editor/src/messages/tool/tool_messages/gradient_tool.rs index 32ce0c9e0b..fdb4aec4ae 100644 --- a/editor/src/messages/tool/tool_messages/gradient_tool.rs +++ b/editor/src/messages/tool/tool_messages/gradient_tool.rs @@ -192,14 +192,22 @@ impl<'a> MessageHandler> for Grad } } - advertise_actions!(GradientToolMessageDiscriminant; - PointerDown, - PointerUp, - PointerMove, - DoubleClick, - Abort, - DeleteStop, - ); + fn actions(&self) -> ActionList { + let mut common = actions!(GradientToolMessageDiscriminant; + PointerDown, + PointerUp, + PointerMove, + DoubleClick, + Abort, + ); + + // Only intercept Delete/Backspace (`DeleteStop`) while a deletable stop or midpoint is selected + if self.data.selected_gradient.as_ref().is_some_and(|selected| !matches!(selected.dragging, GradientDragTarget::New)) { + common.extend(actions!(GradientToolMessageDiscriminant; DeleteStop)); + } + + common + } } impl LayoutHolder for GradientTool { @@ -2327,6 +2335,36 @@ mod test_gradient { assert!(!final_positions.iter().any(|pos| (pos - 0.75).abs() < 0.05), "Stop at position 0.75 should have been deleted"); } + #[tokio::test] + async fn delete_removes_layer_when_no_stop_selected() { + let mut editor = EditorTestUtils::create(); + editor.new_document().await; + + // Create a layer and switch to the Gradient tool without engaging any gradient handle + editor.drag_tool(ToolType::Rectangle, -5., -3., 100., 100., ModifierKeys::empty()).await; + editor.select_tool(ToolType::Gradient).await; + assert_eq!(editor.active_document().metadata().all_layers().count(), 1, "Expected the rectangle layer to exist"); + + // With no color stop selected, Delete should fall through to deleting the selected layer + editor.press(Key::Delete, ModifierKeys::empty()).await; + assert_eq!(editor.active_document().metadata().all_layers().count(), 0, "Expected the layer to be deleted"); + } + + #[tokio::test] + async fn delete_removes_layer_after_drawing_gradient() { + let mut editor = EditorTestUtils::create(); + editor.new_document().await; + + // Draw a fresh gradient, which leaves `selected_gradient` set to the `New` drag target rather than a selected stop + editor.drag_tool(ToolType::Rectangle, -5., -3., 100., 100., ModifierKeys::empty()).await; + editor.drag_tool(ToolType::Gradient, 0., 0., 100., 0., ModifierKeys::empty()).await; + assert_eq!(editor.active_document().metadata().all_layers().count(), 1, "Expected the rectangle layer to exist"); + + // Since no stop is selected (`New` isn't a deletable handle), Delete should still delete the layer + editor.press(Key::Delete, ModifierKeys::empty()).await; + assert_eq!(editor.active_document().metadata().all_layers().count(), 0, "Expected the layer to be deleted after drawing a gradient"); + } + #[tokio::test] async fn change_spread_method() { use graphene_std::vector::style::GradientSpreadMethod;