fix(desktop): add native Edit menu to enable clipboard shortcuts on Linux (#5920)

Co-authored-by: curiouscorrelation <curiouscorrelation@gmail.com>
This commit is contained in:
Umut Keltek 2026-03-19 21:00:22 +03:00 committed by GitHub
parent 4a61e3464d
commit 402955d55f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 2 deletions

View file

@ -164,6 +164,43 @@ pub fn run() {
let app = tauri::Builder::default()
.setup(|app| {
// Set up native Edit menu to enable standard clipboard shortcuts (copy, paste, etc.)
// Required on Linux where webkit2gtk does not handle these without menu items
#[cfg(target_os = "linux")]
{
use tauri::menu::{Menu, PredefinedMenuItem, Submenu};
let result = (|| -> Result<(), Box<dyn std::error::Error>> {
let handle = app.handle();
let edit_menu = Submenu::with_items(
handle,
"Edit",
true,
&[
&PredefinedMenuItem::undo(handle, None)?,
&PredefinedMenuItem::redo(handle, None)?,
&PredefinedMenuItem::separator(handle)?,
&PredefinedMenuItem::cut(handle, None)?,
&PredefinedMenuItem::copy(handle, None)?,
&PredefinedMenuItem::paste(handle, None)?,
&PredefinedMenuItem::separator(handle)?,
&PredefinedMenuItem::select_all(handle, None)?,
],
)?;
// NOTE: This menu bar will be visible on Linux. Removing it or hiding it
// also removes the accelerator registrations and breaks clipboard shortcuts
// (webkit2gtk requires native menu items to recognise Ctrl+C/V/X etc.).
// See https://github.com/tauri-apps/tauri/issues/2397
let menu = Menu::with_items(handle, &[&edit_menu])?;
app.set_menu(menu)?;
Ok(())
})();
if let Err(e) = result {
tracing::warn!(error = %e, "Failed to set up native Edit menu; clipboard shortcuts may not work");
}
}
tauri::async_runtime::block_on(async {
if let Err(e) = setup_version_backup(app).await {
tracing::error!(error = %e, "Failed to setup version backup");

View file

@ -139,8 +139,7 @@ mod tests {
assert_eq!(serialized["access_token"], "token_value");
assert_eq!(serialized["refresh_token"], "refresh_value");
let deserialized: AuthTokensQuery =
serde_json::from_value(serialized).unwrap();
let deserialized: AuthTokensQuery = serde_json::from_value(serialized).unwrap();
assert_eq!(deserialized.access_token, original.access_token);
assert_eq!(deserialized.refresh_token, original.refresh_token);
}