diff --git a/core/tauri/src/window/plugin.rs b/core/tauri/src/window/plugin.rs index 1d295addd..7b6c451e4 100644 --- a/core/tauri/src/window/plugin.rs +++ b/core/tauri/src/window/plugin.rs @@ -215,18 +215,32 @@ mod desktop_commands { /// Initializes the plugin. pub fn init() -> TauriPlugin { + use serialize_to_javascript::{default_template, DefaultTemplate, Template}; + let mut init_script = String::new(); // window.print works on Linux/Windows; need to use the API on macOS #[cfg(any(target_os = "macos", target_os = "ios"))] { init_script.push_str(include_str!("./scripts/print.js")); } - init_script.push_str(include_str!("./scripts/drag.js")); + + #[derive(Template)] + #[default_template("./scripts/drag.js")] + struct Drag<'a> { + os_name: &'a str, + } + + init_script.push_str( + &Drag { + os_name: std::env::consts::OS, + } + .render_default(&Default::default()) + .unwrap() + .into_string(), + ); #[cfg(any(debug_assertions, feature = "devtools"))] { - use serialize_to_javascript::{default_template, DefaultTemplate, Template}; - #[derive(Template)] #[default_template("./scripts/toggle-devtools.js")] struct Devtools<'a> { diff --git a/core/tauri/src/window/scripts/drag.js b/core/tauri/src/window/scripts/drag.js index 96dd64356..925341bfc 100644 --- a/core/tauri/src/window/scripts/drag.js +++ b/core/tauri/src/window/scripts/drag.js @@ -2,16 +2,62 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -document.addEventListener('mousedown', (e) => { - if (e.target.hasAttribute('data-tauri-drag-region') && e.button === 0) { - // prevents text cursor - e.preventDefault() - // fix #2549: double click on drag region edge causes content to maximize without window sizing change - // https://github.com/tauri-apps/tauri/issues/2549#issuecomment-1250036908 - e.stopImmediatePropagation() +;(function () { + const osName = __TEMPLATE_os_name__ - // start dragging if the element has a `tauri-drag-region` data attribute and maximize on double-clicking it - const cmd = e.detail === 2 ? 'internal_toggle_maximize' : 'start_dragging' - window.__TAURI_INTERNALS__.invoke('plugin:window|' + cmd) + //-----------------------// + // drag on mousedown and maximize on double click on Windows and Linux + // while macOS macos maximization should be on mouseup and if the mouse + // moves after the double click, it should be cancelled (see https://github.com/tauri-apps/tauri/issues/8306) + //-----------------------// + const TAURI_DRAG_REGION_ATTR = 'data-tauri-drag-region'; + let x = 0, y = 0; + document.addEventListener('mousedown', (e) => { + if ( + // element has the magic data attribute + e.target.hasAttribute(TAURI_DRAG_REGION_ATTR) && + // and was left mouse button + e.button === 0 && + // and was normal click to drag or double click to maximize + (e.detail === 1 || e.detail === 2) + ) { + + // macOS maximization happens on `mouseup`, + // so we save needed state and early return + if (osName === 'macos' && e.detail == 2) { + x = e.clientX + y = e.clientY + return + } + + // prevents text cursor + e.preventDefault() + + // fix #2549: double click on drag region edge causes content to maximize without window sizing change + // https://github.com/tauri-apps/tauri/issues/2549#issuecomment-1250036908 + e.stopImmediatePropagation() + + // start dragging if the element has a `tauri-drag-region` data attribute and maximize on double-clicking it + const cmd = e.detail === 2 ? 'internal_toggle_maximize' : 'start_dragging' + window.__TAURI_INTERNALS__.invoke('plugin:window|' + cmd) + } + }) + // on macOS we maximze on mouseup instead, to match the system behavior where maximization can be canceled + // if the mouse moves outside the data-tauri-drag-region + if (osName === "macos") { + document.addEventListener('mouseup', (e) => { + if ( + // element has the magic data attribute + e.target.hasAttribute(TAURI_DRAG_REGION_ATTR) && + // and was left mouse button + e.button === 0 && + // and was double click + e.detail === 2 && + // and the cursor hasn't moved from initial mousedown + e.clientX === x && e.clientY === y + ) { + window.__TAURI_INTERNALS__.invoke('plugin:window|internal_toggle_maximize') + } + }) } -}) +})()