Replies: 1 comment
|
You don't need the off-screen You can disable DWM transitions directly on your overlay window's Here is the complete, multi-monitor safe production pattern for Tauri v2: 1. Disable DWM Transitions in RustAdd [dependencies]
tauri = { version = "2", features = [] }
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.59"
features = ["Win32_Graphics_Dwm", "Win32_Foundation"]Apply use tauri::{AppHandle, Manager, WebviewWindow};
#[cfg(windows)]
pub fn disable_window_transitions(window: &WebviewWindow) {
use windows_sys::Win32::Foundation::BOOL;
use windows_sys::Win32::Graphics::Dwm::{DwmSetWindowAttribute, DWMWA_TRANSITIONS_FORCEDISABLED};
if let Ok(hwnd) = window.hwnd() {
let disable: BOOL = 1; // TRUE
unsafe {
DwmSetWindowAttribute(
hwnd.0 as _,
DWMWA_TRANSITIONS_FORCEDISABLED,
&disable as *const _ as *const _,
std::mem::size_of::<BOOL>() as u32,
);
}
}
}Call 2. Multi-Monitor Safe Cursor CenteringTo ensure the overlay always appears on the monitor where your mouse is currently active (and handles different DPI scales seamlessly), calculate coordinates using use tauri::{AppHandle, Manager, PhysicalPosition, PhysicalSize};
pub fn toggle_command_overlay(app: &AppHandle) -> tauri::Result<()> {
let window = match app.get_webview_window("command-palette") {
Some(w) => w,
None => return Ok(()),
};
if window.is_visible()? {
window.hide()?;
} else {
// 1. Get cursor location to identify active monitor
let cursor_pos = app.cursor_position().unwrap_or(PhysicalPosition::new(0.0, 0.0));
// 2. Find the monitor containing the cursor
let current_monitor = app.available_monitors()?.into_iter().find(|m| {
let m_pos = m.position();
let m_size = m.size();
cursor_pos.x >= m_pos.x as f64
&& cursor_pos.x < (m_pos.x + m_size.width as i32) as f64
&& cursor_pos.y >= m_pos.y as f64
&& cursor_pos.y < (m_pos.y + m_size.height as i32) as f64
}).or_else(|| app.primary_monitor().ok().flatten());
if let Some(monitor) = current_monitor {
let monitor_pos = monitor.position();
let monitor_size = monitor.size();
let win_size = window.outer_size()?;
// Center horizontally, place ~25% from top (Raycast standard)
let target_x = monitor_pos.x + ((monitor_size.width as i32 - win_size.width as i32) / 2);
let target_y = monitor_pos.y + ((monitor_size.height as i32 - win_size.height as i32) / 4);
window.set_position(PhysicalPosition::new(target_x, target_y))?;
}
// 3. Instant reveal & grab focus
window.show()?;
window.set_focus()?;
}
Ok(())
}3. Dismiss on Focus Lost (Auto-Hide on Blur)In your app.on_window_event(|window, event| {
if window.label() == "command-palette" {
if let tauri::WindowEvent::Focused(false) = event {
let _ = window.hide();
}
}
});4. Recommended
|
Uh oh!
There was an error while loading. Please reload this page.
I am trying to create a global command menu, similar functionality to raycast using global shortcuts and a second window.
I initially planned to use
window.show()andwindow.hide()methods but it causes unncessary animations on Windows when toggling the display.I found a hacky way to the skip the animation by rendering that window at start and positioning it to
[-10000, -10000]and then positioning it to the center of the monitor the cursor is onI am very skeptical about this approach but this handles the problem i had very well and shows the menu instantly (like in raycast)
Since i do not have access to a second monitor, i am not too sure about how effective this approach is for a multi monitor setup and would not conflict.
Please recommend if there are any better approaches. I am simply trying to mimic raycast's fast window toggle using tauri
Animation at Overlay Exit
Slow_Toggle.1.mp4
Hacky Method Result
Fast_Toggle.1.mp4
All reactions