mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 23:51:44 +08:00
Fix edit menus on windows and linux
This commit is contained in:
parent
c186917c34
commit
3551957c15
@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed Windows+Linux Edit Menu issues by [@leaanthony](https://github.com/leaanthony)
|
||||||
|
|
||||||
## v3.0.0-alpha.9 - 2025-01-13
|
## v3.0.0-alpha.9 - 2025-01-13
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -32,34 +32,77 @@ func NewUnhideMenuItem() *MenuItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewUndoMenuItem() *MenuItem {
|
func NewUndoMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Undo").
|
result := NewMenuItem("Undo").
|
||||||
SetAccelerator("CmdOrCtrl+z")
|
SetAccelerator("CmdOrCtrl+z")
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.undo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRedoMenuItem creates a new menu item for redoing the last action
|
// NewRedoMenuItem creates a new menu item for redoing the last action
|
||||||
func NewRedoMenuItem() *MenuItem {
|
func NewRedoMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Redo").
|
result := NewMenuItem("Redo").
|
||||||
SetAccelerator("CmdOrCtrl+Shift+z")
|
SetAccelerator("CmdOrCtrl+Shift+z")
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.redo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCutMenuItem() *MenuItem {
|
func NewCutMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Cut").
|
result := NewMenuItem("Cut").
|
||||||
SetAccelerator("CmdOrCtrl+x").OnClick(func(ctx *Context) {
|
SetAccelerator("CmdOrCtrl+x")
|
||||||
currentWindow := globalApplication.CurrentWindow()
|
|
||||||
if currentWindow != nil {
|
if runtime.GOOS != "darwin" {
|
||||||
currentWindow.cut()
|
result.OnClick(func(ctx *Context) {
|
||||||
}
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
})
|
if currentWindow != nil {
|
||||||
|
currentWindow.cut()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCopyMenuItem() *MenuItem {
|
func NewCopyMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Copy").
|
result := NewMenuItem("Copy").
|
||||||
SetAccelerator("CmdOrCtrl+c")
|
SetAccelerator("CmdOrCtrl+c")
|
||||||
|
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.copy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasteMenuItem() *MenuItem {
|
func NewPasteMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Paste").
|
result := NewMenuItem("Paste").
|
||||||
SetAccelerator("CmdOrCtrl+v")
|
SetAccelerator("CmdOrCtrl+v")
|
||||||
|
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.paste()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPasteAndMatchStyleMenuItem() *MenuItem {
|
func NewPasteAndMatchStyleMenuItem() *MenuItem {
|
||||||
@ -68,8 +111,18 @@ func NewPasteAndMatchStyleMenuItem() *MenuItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewDeleteMenuItem() *MenuItem {
|
func NewDeleteMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Delete").
|
result := NewMenuItem("Delete").
|
||||||
SetAccelerator("backspace")
|
SetAccelerator("backspace")
|
||||||
|
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.delete()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQuitMenuItem() *MenuItem {
|
func NewQuitMenuItem() *MenuItem {
|
||||||
@ -87,8 +140,18 @@ func NewQuitMenuItem() *MenuItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSelectAllMenuItem() *MenuItem {
|
func NewSelectAllMenuItem() *MenuItem {
|
||||||
return NewMenuItem("Select All").
|
result := NewMenuItem("Select All").
|
||||||
SetAccelerator("CmdOrCtrl+a")
|
SetAccelerator("CmdOrCtrl+a")
|
||||||
|
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
result.OnClick(func(ctx *Context) {
|
||||||
|
currentWindow := globalApplication.CurrentWindow()
|
||||||
|
if currentWindow != nil {
|
||||||
|
currentWindow.selectAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAboutMenuItem() *MenuItem {
|
func NewAboutMenuItem() *MenuItem {
|
||||||
|
@ -1309,42 +1309,49 @@ func (w *WebviewWindow) SetIgnoreMouseEvents(ignore bool) Window {
|
|||||||
|
|
||||||
func (w *WebviewWindow) cut() {
|
func (w *WebviewWindow) cut() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.cut()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.cut()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) copy() {
|
func (w *WebviewWindow) copy() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.copy()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) paste() {
|
func (w *WebviewWindow) paste() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.paste()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.paste()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) selectAll() {
|
func (w *WebviewWindow) selectAll() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.selectAll()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.selectAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) undo() {
|
func (w *WebviewWindow) undo() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.undo()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.undo()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) delete() {
|
func (w *WebviewWindow) delete() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.delete()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebviewWindow) redo() {
|
func (w *WebviewWindow) redo() {
|
||||||
if w.impl == nil || w.isDestroyed() {
|
if w.impl == nil || w.isDestroyed() {
|
||||||
w.impl.redo()
|
return
|
||||||
}
|
}
|
||||||
|
w.impl.redo()
|
||||||
}
|
}
|
||||||
|
@ -74,30 +74,98 @@ type windowsWebviewWindow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) cut() {
|
func (w *windowsWebviewWindow) cut() {
|
||||||
w32.Cut(w.hwnd)
|
w.execJS("document.execCommand('cut')")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) paste() {
|
func (w *windowsWebviewWindow) paste() {
|
||||||
w32.Paste(w.hwnd)
|
w.execJS(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
// Try to read all available formats
|
||||||
|
const clipboardItems = await navigator.clipboard.read();
|
||||||
|
|
||||||
|
for (const clipboardItem of clipboardItems) {
|
||||||
|
// Check for image types
|
||||||
|
for (const type of clipboardItem.types) {
|
||||||
|
if (type.startsWith('image/')) {
|
||||||
|
const blob = await clipboardItem.getType(type);
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
document.execCommand('insertHTML', false, '<img src="' + url + '">');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no image found, try text
|
||||||
|
if (clipboardItem.types.includes('text/plain')) {
|
||||||
|
const text = await navigator.clipboard.readText();
|
||||||
|
document.execCommand('insertText', false, text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
// Fallback to text-only paste if clipboard access fails
|
||||||
|
try {
|
||||||
|
const text = await navigator.clipboard.readText();
|
||||||
|
document.execCommand('insertText', false, text);
|
||||||
|
} catch(fallbackErr) {
|
||||||
|
console.error('Failed to paste:', err, fallbackErr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) copy() {
|
func (w *windowsWebviewWindow) copy() {
|
||||||
w32.Copy(w.hwnd)
|
w.execJS(`
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const selection = window.getSelection();
|
||||||
|
if (!selection.rangeCount) return;
|
||||||
|
|
||||||
|
const range = selection.getRangeAt(0);
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.appendChild(range.cloneContents());
|
||||||
|
|
||||||
|
// Check if we have any images in the selection
|
||||||
|
const images = container.getElementsByTagName('img');
|
||||||
|
if (images.length > 0) {
|
||||||
|
// Handle image copy
|
||||||
|
const img = images[0]; // Take the first image
|
||||||
|
const response = await fetch(img.src);
|
||||||
|
const blob = await response.blob();
|
||||||
|
await navigator.clipboard.write([
|
||||||
|
new ClipboardItem({
|
||||||
|
[blob.type]: blob
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// Handle text copy
|
||||||
|
const text = selection.toString();
|
||||||
|
if (text) {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.error('Failed to copy:', err);
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) selectAll() {
|
func (w *windowsWebviewWindow) selectAll() {
|
||||||
w32.SelectAll(w.hwnd)
|
w.execJS("document.execCommand('selectAll')")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) undo() {
|
func (w *windowsWebviewWindow) undo() {
|
||||||
w32.Undo(w.hwnd)
|
w.execJS("document.execCommand('undo')")
|
||||||
}
|
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) delete() {
|
|
||||||
w32.Delete(w.hwnd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) redo() {
|
func (w *windowsWebviewWindow) redo() {
|
||||||
|
w.execJS("document.execCommand('redo')")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *windowsWebviewWindow) delete() {
|
||||||
|
w.execJS("document.execCommand('delete')")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *windowsWebviewWindow) handleKeyEvent(_ string) {
|
func (w *windowsWebviewWindow) handleKeyEvent(_ string) {
|
||||||
|
Loading…
Reference in New Issue
Block a user