diff --git a/crates/ui/src/docking/native_tests.rs b/crates/ui/src/docking/native_tests.rs index 5cf3dbfb..064d8486 100644 --- a/crates/ui/src/docking/native_tests.rs +++ b/crates/ui/src/docking/native_tests.rs @@ -2205,10 +2205,13 @@ fn a_tab_drag_onto_a_native_window_is_no_app_drag() { #[test] fn a_native_window_fades_only_while_its_drag_can_dock() { let drag = |docks| WindowDrag { window: 1, grab: vec2(10.0, 10.0), to: pos2(100.0, 100.0), start: pos2(100.0, 100.0), docks }; - assert_eq!(drag_opacity(None, true), 1.0); + assert_eq!(drag_opacity(None, false, true), 1.0); // A bar drag that only moves the window stays opaque. - assert_eq!(drag_opacity(Some(&drag(false)), false), 1.0); - assert_eq!(drag_opacity(Some(&drag(false)), true), 0.75); + assert_eq!(drag_opacity(Some(&drag(false)), false, false), 1.0); + assert_eq!(drag_opacity(Some(&drag(false)), false, true), 0.75); // A drag by the window's only tab or group docks either way. - assert_eq!(drag_opacity(Some(&drag(true)), false), 0.75); + assert_eq!(drag_opacity(Some(&drag(true)), false, false), 0.75); + // With Cmd/Ctrl held the drag only moves the window. + assert_eq!(drag_opacity(Some(&drag(false)), true, true), 1.0); + assert_eq!(drag_opacity(Some(&drag(true)), true, false), 1.0); } diff --git a/crates/ui/src/docking/render/native.rs b/crates/ui/src/docking/render/native.rs index 57e494d0..1dd96e49 100644 --- a/crates/ui/src/docking/render/native.rs +++ b/crates/ui/src/docking/render/native.rs @@ -95,11 +95,12 @@ pub(in crate::docking) const OTHER_CLOSE: CloseLayout = const DRAG_OPACITY: f64 = 0.75; /// Opacity of the window `drag` moves: faded while the drag can dock (its only tab or group, or -/// a bar with [`crate::docking::DockStyle::title_bar_docks`]), opaque for a plain move. +/// a bar with [`crate::docking::DockStyle::title_bar_docks`]), opaque for a plain move and while +/// Ctrl/Cmd keeps the drop floating (`float_only`). #[cfg(any(target_os = "macos", test))] -pub(in crate::docking) fn drag_opacity(drag: Option<&WindowDrag>, title_bar_docks: bool) -> f64 { +pub(in crate::docking) fn drag_opacity(drag: Option<&WindowDrag>, float_only: bool, title_bar_docks: bool) -> f64 { match drag { - Some(drag) if drag.docks || title_bar_docks => DRAG_OPACITY, + Some(drag) if !float_only && (drag.docks || title_bar_docks) => DRAG_OPACITY, _ => 1.0, } } @@ -594,7 +595,8 @@ impl Renderer<'_, P> { let drag = ctx.data(|d| d.get_temp::(drag_key)); let dragged = drag.as_ref().and_then(|drag| self.layout.floating.iter().find(|w| w.id == drag.window)); let this = dragged.and_then(|w| crate::docking::dock_model::first_active(&w.root)).is_some_and(|p| self.label_of(p) == title); - let opacity = if this { drag_opacity(drag.as_ref(), self.style.title_bar_docks) } else { 1.0 }; + let float_only = drag.is_some_and(|drag| self.cross.pointer.is_some_and(|p| p.window == Some(drag.window) && p.command)); + let opacity = if this { drag_opacity(drag.as_ref(), float_only, self.style.title_bar_docks) } else { 1.0 }; set_window_opacity(&title, main.as_deref(), opacity); } if let Some(placed) = report.placed.filter(|_| !moving) {