snapshot of https://github.com/tauri-apps/tauri.git (dev, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Audit / audit-js (push) Failing after 0s
bench / bench (map[os:ubuntu-latest runner:xvfb-run --auto-servernum target:x86_64-unknown-linux-gnu], nightly) (push) Failing after 0s
covector version or publish / run-integration-tests (ubuntu-latest) (push) Failing after 0s
Audit / audit-rust (push) Failing after 0s
test `@tauri-apps/cli` / test (ubuntu-latest) (push) Failing after 0s
test `tauri-cli` / test (map[os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
deploy schema worker / deploy (push) Failing after 0s
lint rust / clippy (map[cargo:cargo include: os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
lint rust / clippy (map[cargo:cross include:--package api os:ubuntu-latest target:aarch64-linux-android]) (push) Failing after 0s
supply chain health status / check rust dependencies with cargo vet (push) Failing after 0s
test `@tauri-apps/api` e2e (mobile) / android (push) Failing after 0s
test `@tauri-apps/api` e2e / test (map[name:Linux os:ubuntu-latest]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
Udeps / changes (push) Failing after 0s
Udeps / setup (push) Has been skipped
Udeps / udeps (push) Has been skipped
bench / bench (map[os:macos-latest runner: target:aarch64-apple-darwin], nightly) (push) Has been cancelled
bench / bench (map[os:windows-latest runner: target:x86_64-pc-windows-msvc], nightly) (push) Has been cancelled
covector version or publish / run-integration-tests (macos-latest) (push) Has been cancelled
covector version or publish / run-integration-tests (windows-latest) (push) Has been cancelled
covector version or publish / version-or-publish (push) Has been cancelled
test `@tauri-apps/cli` / test (macos-latest) (push) Has been cancelled
test `tauri-cli` / test (map[args:--no-default-features --features native-tls-vendored os:windows-latest restore-only:true target:aarch64-pc-windows-msvc]) (push) Has been cancelled
test `tauri-cli` / test (map[os:macos-latest target:x86_64-apple-darwin]) (push) Has been cancelled
test `tauri-cli` / test (map[os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:macos-latest target:aarch64-apple-darwin]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include:--package api os:macos-latest target:aarch64-apple-ios]) (push) Has been cancelled
test `@tauri-apps/api` e2e (mobile) / ios (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:Windows os:windows-latest]) (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:macOS os:macos-latest]) (push) Has been cancelled
test `@tauri-apps/cli` / test (windows-latest) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
Some checks failed
Audit / audit-js (push) Failing after 0s
bench / bench (map[os:ubuntu-latest runner:xvfb-run --auto-servernum target:x86_64-unknown-linux-gnu], nightly) (push) Failing after 0s
covector version or publish / run-integration-tests (ubuntu-latest) (push) Failing after 0s
Audit / audit-rust (push) Failing after 0s
test `@tauri-apps/cli` / test (ubuntu-latest) (push) Failing after 0s
test `tauri-cli` / test (map[os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
deploy schema worker / deploy (push) Failing after 0s
lint rust / clippy (map[cargo:cargo include: os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
lint rust / clippy (map[cargo:cross include:--package api os:ubuntu-latest target:aarch64-linux-android]) (push) Failing after 0s
supply chain health status / check rust dependencies with cargo vet (push) Failing after 0s
test `@tauri-apps/api` e2e (mobile) / android (push) Failing after 0s
test `@tauri-apps/api` e2e / test (map[name:Linux os:ubuntu-latest]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
Udeps / changes (push) Failing after 0s
Udeps / setup (push) Has been skipped
Udeps / udeps (push) Has been skipped
bench / bench (map[os:macos-latest runner: target:aarch64-apple-darwin], nightly) (push) Has been cancelled
bench / bench (map[os:windows-latest runner: target:x86_64-pc-windows-msvc], nightly) (push) Has been cancelled
covector version or publish / run-integration-tests (macos-latest) (push) Has been cancelled
covector version or publish / run-integration-tests (windows-latest) (push) Has been cancelled
covector version or publish / version-or-publish (push) Has been cancelled
test `@tauri-apps/cli` / test (macos-latest) (push) Has been cancelled
test `tauri-cli` / test (map[args:--no-default-features --features native-tls-vendored os:windows-latest restore-only:true target:aarch64-pc-windows-msvc]) (push) Has been cancelled
test `tauri-cli` / test (map[os:macos-latest target:x86_64-apple-darwin]) (push) Has been cancelled
test `tauri-cli` / test (map[os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:macos-latest target:aarch64-apple-darwin]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include:--package api os:macos-latest target:aarch64-apple-ios]) (push) Has been cancelled
test `@tauri-apps/api` e2e (mobile) / ios (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:Windows os:windows-latest]) (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:macOS os:macos-latest]) (push) Has been cancelled
test `@tauri-apps/cli` / test (windows-latest) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
This commit is contained in:
2625
crates/tauri/src/window/mod.rs
Normal file
2625
crates/tauri/src/window/mod.rs
Normal file
File diff suppressed because it is too large
Load Diff
351
crates/tauri/src/window/plugin.rs
Normal file
351
crates/tauri/src/window/plugin.rs
Normal file
@@ -0,0 +1,351 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! The tauri plugin to create and manipulate windows from JS.
|
||||
|
||||
use crate::{
|
||||
Runtime, Window,
|
||||
plugin::{Builder, TauriPlugin},
|
||||
sealed::ManagerBase,
|
||||
};
|
||||
|
||||
fn get_window<R: Runtime>(window: Window<R>, label: Option<String>) -> crate::Result<Window<R>> {
|
||||
match label {
|
||||
Some(l) if !l.is_empty() => window
|
||||
.manager()
|
||||
.get_window(&l)
|
||||
.ok_or(crate::Error::WindowNotFound),
|
||||
_ => Ok(window),
|
||||
}
|
||||
}
|
||||
macro_rules! getter {
|
||||
($cmd: ident, $ret: ty) => {
|
||||
#[command(root = "crate")]
|
||||
pub async fn $cmd<R: Runtime>(window: Window<R>, label: Option<String>) -> crate::Result<$ret> {
|
||||
get_window(window, label)?.$cmd().map_err(Into::into)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! setter {
|
||||
($cmd: ident) => {
|
||||
#[command(root = "crate")]
|
||||
pub async fn $cmd<R: Runtime>(window: Window<R>, label: Option<String>) -> crate::Result<()> {
|
||||
get_window(window, label)?.$cmd().map_err(Into::into)
|
||||
}
|
||||
};
|
||||
|
||||
($cmd: ident, $input: ty) => {
|
||||
#[command(root = "crate")]
|
||||
pub async fn $cmd<R: Runtime>(
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
value: $input,
|
||||
) -> crate::Result<()> {
|
||||
get_window(window, label)?.$cmd(value).map_err(Into::into)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mod commands {
|
||||
use tauri_runtime::window::WindowSizeConstraints;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
AppHandle, Monitor, PhysicalPosition, PhysicalSize, Position, Size, Theme, Window, command,
|
||||
sealed::ManagerBase, utils::config::WindowConfig, window::Color, window::WindowBuilder,
|
||||
};
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn get_all_windows<R: Runtime>(app: AppHandle<R>) -> Vec<String> {
|
||||
app.manager().windows().keys().cloned().collect()
|
||||
}
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn create<R: Runtime>(window: Window<R>, options: WindowConfig) -> crate::Result<()> {
|
||||
WindowBuilder::from_config(&window, &options)?.build()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
getter!(scale_factor, f64);
|
||||
getter!(inner_position, PhysicalPosition<i32>);
|
||||
getter!(outer_position, PhysicalPosition<i32>);
|
||||
getter!(inner_size, PhysicalSize<u32>);
|
||||
getter!(outer_size, PhysicalSize<u32>);
|
||||
getter!(is_focused, bool);
|
||||
getter!(is_resizable, bool);
|
||||
getter!(is_visible, bool);
|
||||
getter!(is_enabled, bool);
|
||||
getter!(title, String);
|
||||
getter!(theme, Theme);
|
||||
#[cfg(target_os = "android")]
|
||||
getter!(activity_name, String);
|
||||
#[cfg(target_os = "ios")]
|
||||
getter!(scene_identifier, String);
|
||||
|
||||
setter!(set_resizable, bool);
|
||||
setter!(set_title, &str);
|
||||
setter!(show);
|
||||
setter!(hide);
|
||||
setter!(close);
|
||||
setter!(destroy);
|
||||
setter!(set_content_protected, bool);
|
||||
setter!(set_size, Size);
|
||||
setter!(set_min_size, Option<Size>);
|
||||
setter!(set_max_size, Option<Size>);
|
||||
setter!(set_position, Position);
|
||||
setter!(set_focus);
|
||||
setter!(set_focusable, bool);
|
||||
setter!(set_background_color, Option<Color>);
|
||||
setter!(set_size_constraints, WindowSizeConstraints);
|
||||
setter!(set_theme, Option<Theme>);
|
||||
setter!(set_enabled, bool);
|
||||
|
||||
getter!(current_monitor, Option<Monitor>);
|
||||
getter!(primary_monitor, Option<Monitor>);
|
||||
getter!(available_monitors, Vec<Monitor>);
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn monitor_from_point<R: Runtime>(
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
x: f64,
|
||||
y: f64,
|
||||
) -> crate::Result<Option<Monitor>> {
|
||||
let window = get_window(window, label)?;
|
||||
window.monitor_from_point(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(desktop)]
|
||||
mod desktop_commands {
|
||||
use tauri_runtime::ResizeDirection;
|
||||
use tauri_utils::TitleBarStyle;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
CursorIcon, Manager, PhysicalPosition, Position, UserAttentionType, Webview, command,
|
||||
utils::config::WindowEffectsConfig, window::ProgressBarState,
|
||||
};
|
||||
|
||||
getter!(is_fullscreen, bool);
|
||||
getter!(is_minimized, bool);
|
||||
getter!(is_maximized, bool);
|
||||
getter!(is_decorated, bool);
|
||||
getter!(is_maximizable, bool);
|
||||
getter!(is_minimizable, bool);
|
||||
getter!(is_closable, bool);
|
||||
getter!(cursor_position, PhysicalPosition<f64>);
|
||||
getter!(is_always_on_top, bool);
|
||||
|
||||
setter!(center);
|
||||
setter!(request_user_attention, Option<UserAttentionType>);
|
||||
setter!(set_maximizable, bool);
|
||||
setter!(set_minimizable, bool);
|
||||
setter!(set_closable, bool);
|
||||
setter!(maximize);
|
||||
setter!(unmaximize);
|
||||
setter!(minimize);
|
||||
setter!(unminimize);
|
||||
setter!(set_decorations, bool);
|
||||
setter!(set_shadow, bool);
|
||||
setter!(set_effects, Option<WindowEffectsConfig>);
|
||||
setter!(set_always_on_top, bool);
|
||||
setter!(set_always_on_bottom, bool);
|
||||
setter!(set_fullscreen, bool);
|
||||
setter!(set_fullscreen_on_monitor, PhysicalPosition<f64>);
|
||||
setter!(set_simple_fullscreen, bool);
|
||||
setter!(set_skip_taskbar, bool);
|
||||
setter!(set_cursor_grab, bool);
|
||||
setter!(set_cursor_visible, bool);
|
||||
setter!(set_cursor_icon, CursorIcon);
|
||||
setter!(set_cursor_position, Position);
|
||||
setter!(set_ignore_cursor_events, bool);
|
||||
setter!(start_dragging);
|
||||
setter!(start_resize_dragging, ResizeDirection);
|
||||
setter!(set_progress_bar, ProgressBarState);
|
||||
setter!(set_badge_count, Option<i64>);
|
||||
#[cfg(target_os = "macos")]
|
||||
setter!(set_badge_label, Option<String>);
|
||||
setter!(set_visible_on_all_workspaces, bool);
|
||||
setter!(set_title_bar_style, TitleBarStyle);
|
||||
|
||||
#[command(root = "crate")]
|
||||
#[cfg(target_os = "windows")]
|
||||
pub async fn set_overlay_icon<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
value: Option<crate::image::JsImage>,
|
||||
) -> crate::Result<()> {
|
||||
let window = get_window(window, label)?;
|
||||
let resources_table = webview.resources_table();
|
||||
|
||||
let value = match value {
|
||||
Some(value) => Some(value.into_img(&resources_table)?.as_ref().clone()),
|
||||
None => None,
|
||||
};
|
||||
|
||||
window.set_overlay_icon(value)
|
||||
}
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn set_icon<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
value: crate::image::JsImage,
|
||||
) -> crate::Result<()> {
|
||||
let window = get_window(window, label)?;
|
||||
let resources_table = webview.resources_table();
|
||||
window.set_icon(value.into_img(&resources_table)?.as_ref().clone())
|
||||
}
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn toggle_maximize<R: Runtime>(
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
) -> crate::Result<()> {
|
||||
let window = get_window(window, label)?;
|
||||
if window.is_maximized()? {
|
||||
window.unmaximize()?
|
||||
} else {
|
||||
window.maximize()?
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command(root = "crate")]
|
||||
pub async fn internal_toggle_maximize<R: Runtime>(
|
||||
window: Window<R>,
|
||||
label: Option<String>,
|
||||
) -> crate::Result<()> {
|
||||
let window = get_window(window, label)?;
|
||||
if window.is_resizable()? {
|
||||
if window.is_maximized()? {
|
||||
window.unmaximize()?
|
||||
} else if window.is_maximizable()? {
|
||||
window.maximize()?
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes the plugin.
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
use serialize_to_javascript::{DefaultTemplate, Template, default_template};
|
||||
|
||||
let mut init_script = String::new();
|
||||
|
||||
#[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(),
|
||||
);
|
||||
|
||||
Builder::new("window")
|
||||
.js_init_script(init_script)
|
||||
.invoke_handler(crate::generate_handler![
|
||||
#![plugin(window)]
|
||||
commands::create,
|
||||
// getters
|
||||
commands::get_all_windows,
|
||||
commands::scale_factor,
|
||||
commands::inner_position,
|
||||
commands::outer_position,
|
||||
commands::inner_size,
|
||||
commands::outer_size,
|
||||
commands::is_focused,
|
||||
commands::is_resizable,
|
||||
commands::is_visible,
|
||||
commands::is_enabled,
|
||||
commands::title,
|
||||
commands::theme,
|
||||
#[cfg(target_os = "android")]
|
||||
commands::activity_name,
|
||||
#[cfg(target_os = "ios")]
|
||||
commands::scene_identifier,
|
||||
|
||||
commands::set_resizable,
|
||||
commands::set_title,
|
||||
commands::show,
|
||||
commands::hide,
|
||||
commands::close,
|
||||
commands::destroy,
|
||||
commands::set_content_protected,
|
||||
commands::set_size,
|
||||
commands::set_min_size,
|
||||
commands::set_max_size,
|
||||
commands::set_position,
|
||||
commands::set_size_constraints,
|
||||
commands::set_focus,
|
||||
commands::set_focusable,
|
||||
commands::set_enabled,
|
||||
commands::set_background_color,
|
||||
commands::set_theme,
|
||||
commands::current_monitor,
|
||||
commands::primary_monitor,
|
||||
commands::monitor_from_point,
|
||||
commands::available_monitors,
|
||||
|
||||
#[cfg(desktop)] desktop_commands::is_fullscreen,
|
||||
#[cfg(desktop)] desktop_commands::is_minimized,
|
||||
#[cfg(desktop)] desktop_commands::is_maximized,
|
||||
#[cfg(desktop)] desktop_commands::is_decorated,
|
||||
#[cfg(desktop)] desktop_commands::is_maximizable,
|
||||
#[cfg(desktop)] desktop_commands::is_minimizable,
|
||||
#[cfg(desktop)] desktop_commands::is_closable,
|
||||
|
||||
#[cfg(desktop)] desktop_commands::cursor_position,
|
||||
#[cfg(desktop)] desktop_commands::is_always_on_top,
|
||||
// setters
|
||||
#[cfg(desktop)] desktop_commands::center,
|
||||
#[cfg(desktop)] desktop_commands::request_user_attention,
|
||||
#[cfg(desktop)] desktop_commands::set_maximizable,
|
||||
#[cfg(desktop)] desktop_commands::set_minimizable,
|
||||
#[cfg(desktop)] desktop_commands::set_closable,
|
||||
#[cfg(desktop)] desktop_commands::maximize,
|
||||
#[cfg(desktop)] desktop_commands::unmaximize,
|
||||
#[cfg(desktop)] desktop_commands::minimize,
|
||||
#[cfg(desktop)] desktop_commands::unminimize,
|
||||
#[cfg(desktop)] desktop_commands::set_decorations,
|
||||
#[cfg(desktop)] desktop_commands::set_shadow,
|
||||
#[cfg(desktop)] desktop_commands::set_effects,
|
||||
#[cfg(desktop)] desktop_commands::set_always_on_top,
|
||||
#[cfg(desktop)] desktop_commands::set_always_on_bottom,
|
||||
#[cfg(desktop)] desktop_commands::set_fullscreen,
|
||||
#[cfg(desktop)] desktop_commands::set_fullscreen_on_monitor,
|
||||
#[cfg(desktop)] desktop_commands::set_simple_fullscreen,
|
||||
#[cfg(desktop)] desktop_commands::set_skip_taskbar,
|
||||
#[cfg(desktop)] desktop_commands::set_cursor_grab,
|
||||
#[cfg(desktop)] desktop_commands::set_cursor_visible,
|
||||
#[cfg(desktop)] desktop_commands::set_cursor_icon,
|
||||
#[cfg(desktop)] desktop_commands::set_cursor_position,
|
||||
#[cfg(desktop)] desktop_commands::set_ignore_cursor_events,
|
||||
#[cfg(desktop)] desktop_commands::start_dragging,
|
||||
#[cfg(desktop)] desktop_commands::start_resize_dragging,
|
||||
#[cfg(desktop)] desktop_commands::set_badge_count,
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(desktop)] desktop_commands::set_badge_label,
|
||||
#[cfg(desktop)] desktop_commands::set_progress_bar,
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(desktop)] desktop_commands::set_overlay_icon,
|
||||
#[cfg(desktop)] desktop_commands::set_icon,
|
||||
#[cfg(desktop)] desktop_commands::set_visible_on_all_workspaces,
|
||||
#[cfg(desktop)] desktop_commands::set_title_bar_style,
|
||||
#[cfg(desktop)] desktop_commands::toggle_maximize,
|
||||
#[cfg(desktop)] desktop_commands::internal_toggle_maximize,
|
||||
])
|
||||
.build()
|
||||
}
|
||||
129
crates/tauri/src/window/scripts/drag.js
Normal file
129
crates/tauri/src/window/scripts/drag.js
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
;(function () {
|
||||
//-----------------------//
|
||||
// drag on mousedown and maximize on double click on Windows and Linux
|
||||
// while 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'
|
||||
const CLICKABLE_TAGS = new Set([
|
||||
'A',
|
||||
'BUTTON',
|
||||
'INPUT',
|
||||
'SELECT',
|
||||
'TEXTAREA',
|
||||
'LABEL',
|
||||
'SUMMARY'
|
||||
])
|
||||
const INTERACTIVE_ROLES = new Set([
|
||||
'button',
|
||||
'link',
|
||||
'menuitem',
|
||||
'tab',
|
||||
'checkbox',
|
||||
'radio',
|
||||
'switch',
|
||||
'option'
|
||||
])
|
||||
|
||||
function isClickableElement(el) {
|
||||
return (
|
||||
CLICKABLE_TAGS.has(el.tagName)
|
||||
|| (el.hasAttribute('contenteditable')
|
||||
&& el.getAttribute('contenteditable') !== 'false')
|
||||
|| (el.hasAttribute('tabindex') && el.getAttribute('tabindex') !== '-1')
|
||||
|| INTERACTIVE_ROLES.has(el.getAttribute('role'))
|
||||
)
|
||||
}
|
||||
|
||||
// Walk the composed path from target upward.
|
||||
//
|
||||
// Supported values for data-tauri-drag-region:
|
||||
// (bare / no value / "true") -> self: only direct clicks on this element trigger drag
|
||||
// "deep" -> deep: clicks anywhere in the subtree trigger drag
|
||||
// "false" -> disabled: drag is blocked here (and for ancestors)
|
||||
//
|
||||
// Clickable elements (buttons, links, etc.) normally block dragging,
|
||||
// but if they themselves carry data-tauri-drag-region they act as drag regions.
|
||||
function isDragRegion(composedPath) {
|
||||
for (const el of composedPath) {
|
||||
if (!(el instanceof HTMLElement)) continue
|
||||
|
||||
const attr = el.getAttribute(TAURI_DRAG_REGION_ATTR)
|
||||
|
||||
// clickable without explicit drag region → blocks drag
|
||||
if (isClickableElement(el) && attr === null) return false
|
||||
// no attr → keep walking up
|
||||
if (attr === null) continue
|
||||
// explicitly disabled
|
||||
if (attr === 'false') return false
|
||||
// subtree drag — any descendant triggers
|
||||
if (attr === 'deep') return true
|
||||
// bare or "true" attr — only direct clicks on this element
|
||||
if (attr === '' || attr === 'true') return el === composedPath[0]
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const osName = __TEMPLATE_os_name__
|
||||
|
||||
// initial mousedown position for macOS
|
||||
let initialX = 0
|
||||
let initialY = 0
|
||||
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (
|
||||
// was left mouse button
|
||||
e.button === 0
|
||||
// and was normal click to drag or double click to maximize
|
||||
&& (e.detail === 1 || e.detail === 2)
|
||||
// and is drag region
|
||||
&& isDragRegion(e.composedPath())
|
||||
) {
|
||||
// macOS maximization happens on `mouseup`,
|
||||
// so we save needed state and early return
|
||||
if (osName === 'macos' && e.detail === 2) {
|
||||
initialX = e.clientX
|
||||
initialY = 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 maximize 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 (
|
||||
// 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 === initialX
|
||||
&& e.clientY === initialY
|
||||
// and the event path contains a drag region (with no clickable element in between)
|
||||
&& isDragRegion(e.composedPath())
|
||||
) {
|
||||
window.__TAURI_INTERNALS__.invoke(
|
||||
'plugin:window|internal_toggle_maximize'
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})()
|
||||
Reference in New Issue
Block a user