diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index 732b8ccd8..82f2c2ea8 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -29,9 +29,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [linux] Fixed linux compile error introduced by IgnoreMouseEvents addition by [atterpac](https://github.com/atterpac) in [#3721](https://github.com/wailsapp/wails/pull/3721) - [windows] Fixed syso icon file generation bug by [atterpac](https://github.com/atterpac) in [#3675](https://github.com/wailsapp/wails/pull/3675) - [linux] Fix to run natively in wayland incorporated from [#1811](https://github.com/wailsapp/wails/pull/1811) in [#3614](https://github.com/wailsapp/wails/pull/3614) by [@stendler](https://github.com/stendler) -- Do not bind internal service methods in [#3720](https://github.com/wailsapp/wails/pull/3720) - by [leaanthony](https://github.com/leaanthony) +- Do not bind internal service methods in [#3720](https://github.com/wailsapp/wails/pull/3720) by [leaanthony](https://github.com/leaanthony) - [windows] Fixed system tray startup panic in [#3693](https://github.com/wailsapp/wails/issues/3693) by [@DeltaLaboratory](https://github.com/DeltaLaboratory) +- Do not bind internal service methods in [#3720](https://github.com/wailsapp/wails/pull/3720) by [leaanthony](https://github.com/leaanthony) +- [windows] Fixed system tray startup panic in [#3693](https://github.com/wailsapp/wails/issues/3693) by [@DeltaLaboratory](https://github.com/DeltaLaboratory) +- Major menu item refactor and event handling. Mainly improves macOS for now. By [leaanthony](https://github.com/leaanthony) ## v3.0.0-alpha.6 - 2024-07-30 diff --git a/v3/examples/dialogs/main.go b/v3/examples/dialogs/main.go index b06ba3a6c..910b30367 100644 --- a/v3/examples/dialogs/main.go +++ b/v3/examples/dialogs/main.go @@ -28,6 +28,10 @@ func main() { // Create a custom menu menu := app.NewMenu() menu.AddRole(application.AppMenu) + menu.AddRole(application.EditMenu) + menu.AddRole(application.WindowMenu) + menu.AddRole(application.ServicesMenu) + menu.AddRole(application.HelpMenu) // Let's make a "Demo" menu infoMenu := menu.AddSubmenu("Info") diff --git a/v3/examples/menu/main.go b/v3/examples/menu/main.go index c8df3016e..148306fe0 100644 --- a/v3/examples/menu/main.go +++ b/v3/examples/menu/main.go @@ -27,6 +27,19 @@ func main() { if runtime.GOOS == "darwin" { menu.AddRole(application.AppMenu) } + fileMenu := menu.AddRole(application.FileMenu) + _ = fileMenu + //fileMenu.FindByRole(application.Open).OnClick(func(context *application.Context) { + // selection, err := application.OpenFileDialog().PromptForSingleSelection() + // if err != nil { + // println("Error: " + err.Error()) + // return + // } + // println("You selected: " + selection) + //}) + menu.AddRole(application.EditMenu) + menu.AddRole(application.WindowMenu) + menu.AddRole(application.HelpMenu) // Let's make a "Demo" menu myMenu := menu.AddSubmenu("Demo") diff --git a/v3/examples/systray/main.go b/v3/examples/systray/main.go index c28531520..6b3567b15 100644 --- a/v3/examples/systray/main.go +++ b/v3/examples/systray/main.go @@ -21,7 +21,7 @@ func main() { systemTray := app.NewSystemTray() - window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + _ = app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Width: 500, Height: 800, Name: "Systray Demo Window", @@ -92,7 +92,8 @@ func main() { }) systemTray.SetMenu(myMenu) - systemTray.AttachWindow(window).WindowOffset(5) + + //systemTray.AttachWindow(window).WindowOffset(5) err := app.Run() if err != nil { diff --git a/v3/go.mod b/v3/go.mod index b15a9819e..d85b2bb62 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -29,7 +29,7 @@ require ( github.com/pterm/pterm v0.12.51 github.com/samber/lo v1.38.1 github.com/tc-hib/winres v0.3.1 - github.com/wailsapp/go-webview2 v1.0.11 + github.com/wailsapp/go-webview2 v1.0.15 github.com/wailsapp/mimetype v1.4.1 golang.org/x/sys v0.20.0 golang.org/x/term v0.20.0 diff --git a/v3/go.sum b/v3/go.sum index 9fbb487c2..79c14b654 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -219,6 +219,8 @@ github.com/tc-hib/winres v0.3.1 h1:CwRjEGrKdbi5CvZ4ID+iyVhgyfatxFoizjPhzez9Io4= github.com/tc-hib/winres v0.3.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= github.com/wailsapp/go-webview2 v1.0.11 h1:CDbU4UQpaERY6M/FGObPGzUsFOHH3Yz+go12qnJINNY= github.com/wailsapp/go-webview2 v1.0.11/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= +github.com/wailsapp/go-webview2 v1.0.15 h1:IeQFoWmsHp32y64I41J+Zod3SopjHs918KSO4jUqEnY= +github.com/wailsapp/go-webview2 v1.0.15/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= diff --git a/v3/pkg/application/menu.go b/v3/pkg/application/menu.go index ba2c60c21..c67951b9d 100644 --- a/v3/pkg/application/menu.go +++ b/v3/pkg/application/menu.go @@ -112,6 +112,23 @@ func (m *Menu) FindByLabel(label string) *MenuItem { return nil } +// FindByRole recursively searches for a menu item with the given role +// and returns the first match, or nil if not found. +func (m *Menu) FindByRole(role Role) *MenuItem { + for _, item := range m.items { + if item.role == role { + return item + } + if item.submenu != nil { + found := item.submenu.FindByRole(role) + if found != nil { + return found + } + } + } + return nil +} + func (m *Menu) RemoveMenuItem(target *MenuItem) { for i, item := range m.items { if item == target { diff --git a/v3/pkg/application/menuitem.go b/v3/pkg/application/menuitem.go index 11fbb48e2..71ea0cd00 100644 --- a/v3/pkg/application/menuitem.go +++ b/v3/pkg/application/menuitem.go @@ -116,77 +116,119 @@ func NewSubMenuItem(label string) *MenuItem { } func NewRole(role Role) *MenuItem { + var result *MenuItem switch role { case AppMenu: - return newAppMenu() + result = NewAppMenu() case EditMenu: - return newEditMenu() + result = NewEditMenu() case FileMenu: - return newFileMenu() + result = NewFileMenu() case ViewMenu: - return newViewMenu() + result = NewViewMenu() case ServicesMenu: return NewServicesMenu() case SpeechMenu: - return newSpeechMenu() + result = NewSpeechMenu() case WindowMenu: - return newWindowMenu() + result = NewWindowMenu() case HelpMenu: - return newHelpMenu() + result = NewHelpMenu() case Hide: - return newHideMenuItem() + result = NewHideMenuItem() + case Front: + result = NewFrontMenuItem() case HideOthers: - return newHideOthersMenuItem() + result = NewHideOthersMenuItem() case UnHide: - return newUnhideMenuItem() + result = NewUnhideMenuItem() case Undo: - return newUndoMenuItem() + result = NewUndoMenuItem() case Redo: - return newRedoMenuItem() + result = NewRedoMenuItem() case Cut: - return newCutMenuItem() + result = NewCutMenuItem() case Copy: - return newCopyMenuItem() + result = NewCopyMenuItem() case Paste: - return newPasteMenuItem() + result = NewPasteMenuItem() case PasteAndMatchStyle: - return newPasteAndMatchStyleMenuItem() + result = NewPasteAndMatchStyleMenuItem() case SelectAll: - return newSelectAllMenuItem() + result = NewSelectAllMenuItem() case Delete: - return newDeleteMenuItem() + result = NewDeleteMenuItem() case Quit: - return newQuitMenuItem() - case Close: - return newCloseMenuItem() + result = NewQuitMenuItem() + case CloseWindow: + result = NewCloseMenuItem() case About: - return newAboutMenuItem() + result = NewAboutMenuItem() case Reload: - return newReloadMenuItem() + result = NewReloadMenuItem() case ForceReload: - return newForceReloadMenuItem() + result = NewForceReloadMenuItem() case ToggleFullscreen: - return newToggleFullscreenMenuItem() + result = NewToggleFullscreenMenuItem() case OpenDevTools: - return newOpenDevToolsMenuItem() + result = NewOpenDevToolsMenuItem() case ResetZoom: - return newZoomResetMenuItem() + result = NewZoomResetMenuItem() case ZoomIn: - return newZoomInMenuItem() + result = NewZoomInMenuItem() case ZoomOut: - return newZoomOutMenuItem() + result = NewZoomOutMenuItem() case Minimize: - return newMinimizeMenuItem() + result = NewMinimizeMenuItem() case Zoom: - return newZoomMenuItem() + result = NewZoomMenuItem() case FullScreen: - return newFullScreenMenuItem() + result = NewFullScreenMenuItem() + case Print: + result = NewPrintMenuItem() + case PageLayout: + result = NewPageLayoutMenuItem() + case NoRole: + case ShowAll: + result = NewShowAllMenuItem() + case BringAllToFront: + result = NewBringAllToFrontMenuItem() + case NewFile: + result = NewNewFileMenuItem() + case Open: + result = NewOpenMenuItem() + case Save: + result = NewSaveMenuItem() + case SaveAs: + result = NewSaveAsMenuItem() + case StartSpeaking: + result = NewStartSpeakingMenuItem() + case StopSpeaking: + result = NewStopSpeakingMenuItem() + case Revert: + result = NewRevertMenuItem() + case Find: + result = NewFindMenuItem() + case FindAndReplace: + result = NewFindAndReplaceMenuItem() + case FindNext: + result = NewFindNextMenuItem() + case FindPrevious: + result = NewFindPreviousMenuItem() + case Help: + result = NewHelpMenuItem() default: globalApplication.error(fmt.Sprintf("No support for role: %v", role)) os.Exit(1) } - return nil + + if result == nil { + return nil + } + + result.role = role + return result } func NewServicesMenu() *MenuItem { @@ -256,6 +298,11 @@ func (m *MenuItem) SetTooltip(s string) *MenuItem { return m } +func (m *MenuItem) SetRole(role Role) *MenuItem { + m.role = role + return m +} + func (m *MenuItem) SetLabel(s string) *MenuItem { m.label = s if m.impl != nil { diff --git a/v3/pkg/application/menuitem_darwin.go b/v3/pkg/application/menuitem_darwin.go index 69855542a..22f6aa6ae 100644 --- a/v3/pkg/application/menuitem_darwin.go +++ b/v3/pkg/application/menuitem_darwin.go @@ -13,8 +13,9 @@ package application #define unicode(input) [NSString stringWithFormat:@"%C", input] // Create menu item -void* newMenuItem(unsigned int menuItemID, char *label, bool disabled, char* tooltip) { - MenuItem *menuItem = [MenuItem new]; +void* newMenuItem(unsigned int menuItemID, char *label, bool disabled, char* tooltip, char* selector) { + NSLog(@"newMenuItem: %s, %s\n", label, selector); + MenuItem *menuItem = [MenuItem new]; // Label menuItem.title = [NSString stringWithUTF8String:label]; @@ -22,10 +23,16 @@ void* newMenuItem(unsigned int menuItemID, char *label, bool disabled, char* too if( disabled ) { [menuItem setTarget:nil]; } else { - [menuItem setTarget:menuItem]; + if (selector != NULL) { + menuItem.action = NSSelectorFromString([NSString stringWithUTF8String:selector]); + menuItem.target = nil; // Allow the action to be sent up the responder chain + } else { + menuItem.action = @selector(handleClick); + menuItem.target = menuItem; + } } menuItem.menuItemID = menuItemID; - menuItem.action = @selector(handleClick); + menuItem.enabled = !disabled; // Tooltip @@ -269,21 +276,6 @@ static char *pasteFromPasteboard(void) { return strdup([text UTF8String]); } -// Call paste selector to paste text -static void paste(void) { - [NSApp sendAction:@selector(paste:) to:nil from:nil]; -} - -// Call copy selector to copy text -static void copy(void) { - [NSApp sendAction:@selector(copy:) to:nil from:nil]; -} - -// Call cut selector to cut text -static void cut(void) { - [NSApp sendAction:@selector(cut:) to:nil from:nil]; -} - void performSelectorOnMainThreadForFirstResponder(SEL selector) { NSWindow *activeWindow = [[NSApplication sharedApplication] keyWindow]; if (activeWindow) { @@ -291,54 +283,6 @@ void performSelectorOnMainThreadForFirstResponder(SEL selector) { } } -// Call selectAll selector to select all text -static void selectAll(void) { - performSelectorOnMainThreadForFirstResponder(@selector(selectAll:)); -} - -// Call delete selector to delete text -static void delete(void) { - [NSApp sendAction:@selector(delete:) to:nil from:nil]; -} - -// Call undo selector to undo text -static void undo(void) { - [NSApp sendAction:@selector(undo:) to:nil from:nil]; -} - -// Call redo selector to redo text -static void redo(void) { - [NSApp sendAction:@selector(redo:) to:nil from:nil]; -} - -// Call startSpeaking selector to start speaking text -static void startSpeaking(void) { - [NSApp sendAction:@selector(startSpeaking:) to:nil from:nil]; -} - -// Call stopSpeaking selector to stop speaking text -static void stopSpeaking(void) { - [NSApp sendAction:@selector(stopSpeaking:) to:nil from:nil]; -} - -static void pasteAndMatchStyle(void) { - [NSApp sendAction:@selector(pasteAndMatchStyle:) to:nil from:nil]; -} - -static void hideApplication(void) { - [[NSApplication sharedApplication] hide:nil]; -} - -// hideOthers hides all other applications -static void hideOthers(void) { - [[NSApplication sharedApplication] hideOtherApplications:nil]; -} - -// showAll shows all hidden applications -static void showAll(void) { - [[NSApplication sharedApplication] unhideAllApplications:nil]; -} - void setMenuItemBitmap(void* nsMenuItem, unsigned char *bitmap, int length) { MenuItem *menuItem = (MenuItem *)nsMenuItem; NSImage *image = [[NSImage alloc] initWithData:[NSData dataWithBytes:bitmap length:length]]; @@ -347,7 +291,6 @@ void setMenuItemBitmap(void* nsMenuItem, unsigned char *bitmap, int length) { */ import "C" import ( - "runtime" "unsafe" ) @@ -399,251 +342,25 @@ func newMenuItemImpl(item *MenuItem) *macosMenuItem { menuItem: item, } + selector := getSelectorForRole(item.role) + if selector != nil { + defer C.free(unsafe.Pointer(selector)) + } + result.nsMenuItem = unsafe.Pointer(C.newMenuItem( + C.uint(item.id), + C.CString(item.label), + C.bool(item.disabled), + C.CString(item.tooltip), + selector, + )) + switch item.itemType { - case text, checkbox, submenu, radio: - result.nsMenuItem = unsafe.Pointer(C.newMenuItem(C.uint(item.id), C.CString(item.label), C.bool(item.disabled), C.CString(item.tooltip))) - if item.itemType == checkbox || item.itemType == radio { - C.setMenuItemChecked(result.nsMenuItem, C.bool(item.checked)) - } - if item.accelerator != nil { - result.setAccelerator(item.accelerator) - } - default: - panic("WTF") + case checkbox, radio: + C.setMenuItemChecked(result.nsMenuItem, C.bool(item.checked)) + } + + if item.accelerator != nil { + result.setAccelerator(item.accelerator) } return result } - -func newSpeechMenu() *MenuItem { - speechMenu := NewMenu() - speechMenu.Add("Start Speaking"). - SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+."). - OnClick(func(ctx *Context) { - C.startSpeaking() - }) - speechMenu.Add("Stop Speaking"). - SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+,"). - OnClick(func(ctx *Context) { - C.stopSpeaking() - }) - subMenu := NewSubMenuItem("Speech") - subMenu.submenu = speechMenu - return subMenu -} - -func newHideMenuItem() *MenuItem { - return NewMenuItem("Hide " + globalApplication.options.Name). - SetAccelerator("CmdOrCtrl+h"). - OnClick(func(ctx *Context) { - C.hideApplication() - }) -} - -func newHideOthersMenuItem() *MenuItem { - return NewMenuItem("Hide Others"). - SetAccelerator("CmdOrCtrl+OptionOrAlt+h"). - OnClick(func(ctx *Context) { - C.hideOthers() - }) -} - -func newUnhideMenuItem() *MenuItem { - return NewMenuItem("Show All"). - OnClick(func(ctx *Context) { - C.showAll() - }) -} - -func newUndoMenuItem() *MenuItem { - return NewMenuItem("Undo"). - SetAccelerator("CmdOrCtrl+z"). - OnClick(func(ctx *Context) { - C.undo() - }) -} - -// newRedoMenuItem creates a new menu item for redoing the last action -func newRedoMenuItem() *MenuItem { - return NewMenuItem("Redo"). - SetAccelerator("CmdOrCtrl+Shift+z"). - OnClick(func(ctx *Context) { - C.redo() - }) -} - -func newCutMenuItem() *MenuItem { - return NewMenuItem("Cut"). - SetAccelerator("CmdOrCtrl+x"). - OnClick(func(ctx *Context) { - C.cut() - }) -} - -func newCopyMenuItem() *MenuItem { - return NewMenuItem("Copy"). - SetAccelerator("CmdOrCtrl+c"). - OnClick(func(ctx *Context) { - C.copy() - }) -} - -func newPasteMenuItem() *MenuItem { - return NewMenuItem("Paste"). - SetAccelerator("CmdOrCtrl+v"). - OnClick(func(ctx *Context) { - C.paste() - }) -} - -func newPasteAndMatchStyleMenuItem() *MenuItem { - return NewMenuItem("Paste and Match Style"). - SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+v"). - OnClick(func(ctx *Context) { - C.pasteAndMatchStyle() - }) -} - -func newDeleteMenuItem() *MenuItem { - return NewMenuItem("Delete"). - SetAccelerator("backspace"). - OnClick(func(ctx *Context) { - C.delete() - }) -} - -func newQuitMenuItem() *MenuItem { - return NewMenuItem("Quit " + globalApplication.options.Name). - SetAccelerator("CmdOrCtrl+q"). - OnClick(func(ctx *Context) { - globalApplication.Quit() - }) -} - -func newSelectAllMenuItem() *MenuItem { - return NewMenuItem("Select All"). - SetAccelerator("CmdOrCtrl+a"). - OnClick(func(ctx *Context) { - C.selectAll() - }) -} - -func newAboutMenuItem() *MenuItem { - return NewMenuItem("About " + globalApplication.options.Name). - OnClick(func(ctx *Context) { - globalApplication.ShowAboutDialog() - }) -} - -func newCloseMenuItem() *MenuItem { - return NewMenuItem("Close"). - SetAccelerator("CmdOrCtrl+w"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Close() - } - }) -} - -func newReloadMenuItem() *MenuItem { - return NewMenuItem("Reload"). - SetAccelerator("CmdOrCtrl+r"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Reload() - } - }) -} - -func newForceReloadMenuItem() *MenuItem { - return NewMenuItem("Force Reload"). - SetAccelerator("CmdOrCtrl+Shift+r"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ForceReload() - } - }) -} - -func newToggleFullscreenMenuItem() *MenuItem { - result := NewMenuItem("Toggle Full Screen"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ToggleFullscreen() - } - }) - if runtime.GOOS == "darwin" { - result.SetAccelerator("Ctrl+Command+F") - } else { - result.SetAccelerator("F11") - } - return result -} - -func newZoomResetMenuItem() *MenuItem { - // reset zoom menu item - return NewMenuItem("Actual Size"). - SetAccelerator("CmdOrCtrl+0"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomReset() - } - }) -} - -func newZoomInMenuItem() *MenuItem { - return NewMenuItem("Zoom In"). - SetAccelerator("CmdOrCtrl+plus"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomIn() - } - }) -} - -func newZoomOutMenuItem() *MenuItem { - return NewMenuItem("Zoom Out"). - SetAccelerator("CmdOrCtrl+-"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomOut() - } - }) -} - -func newMinimizeMenuItem() *MenuItem { - return NewMenuItem("Minimize"). - SetAccelerator("CmdOrCtrl+M"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Minimise() - } - }) -} - -func newZoomMenuItem() *MenuItem { - return NewMenuItem("Zoom"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Zoom() - } - }) -} - -func newFullScreenMenuItem() *MenuItem { - return NewMenuItem("Fullscreen"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Fullscreen() - } - }) -} diff --git a/v3/pkg/application/menuitem_dev.go b/v3/pkg/application/menuitem_dev.go index 24f6f06bd..7eb2a44ae 100644 --- a/v3/pkg/application/menuitem_dev.go +++ b/v3/pkg/application/menuitem_dev.go @@ -2,7 +2,7 @@ package application -func newOpenDevToolsMenuItem() *MenuItem { +func NewOpenDevToolsMenuItem() *MenuItem { return NewMenuItem("Open Developer Tools"). SetAccelerator("Alt+Command+I"). OnClick(func(ctx *Context) { diff --git a/v3/pkg/application/menuitem_linux.go b/v3/pkg/application/menuitem_linux.go index 4c1447c03..ca22d7452 100644 --- a/v3/pkg/application/menuitem_linux.go +++ b/v3/pkg/application/menuitem_linux.go @@ -141,6 +141,10 @@ func newSpeechMenu() *MenuItem { return subMenu } +func newFrontMenuItem() *MenuItem { + panic("implement me") +} + func newHideMenuItem() *MenuItem { return NewMenuItem("Hide " + globalApplication.options.Name). SetAccelerator("CmdOrCtrl+h"). @@ -358,3 +362,67 @@ func newFullScreenMenuItem() *MenuItem { } }) } + +func newPrintMenuItem() *MenuItem { + panic("Implement me") +} + +func newPageLayoutMenuItem() *MenuItem { + panic("Implement me") +} + +func newShowAllMenuItem() *MenuItem { + panic("Implement me") +} + +func newBringAllToFrontMenuItem() *MenuItem { + panic("Implement me") +} + +func newNewFileMenuItem() *MenuItem { + panic("Implement me") +} + +func newOpenMenuItem() *MenuItem { + panic("Implement me") +} + +func newSaveMenuItem() *MenuItem { + panic("Implement me") +} + +func newSaveAsMenuItem() *MenuItem { + panic("Implement me") +} + +func newStartSpeakingMenuItem() *MenuItem { + panic("Implement me") +} + +func newStopSpeakingMenuItem() *MenuItem { + panic("Implement me") +} + +func newRevertMenuItem() *MenuItem { + panic("Implement me") +} + +func newFindMenuItem() *MenuItem { + panic("Implement me") +} + +func newFindAndReplaceMenuItem() *MenuItem { + panic("Implement me") +} + +func newFindNextMenuItem() *MenuItem { + panic("Implement me") +} + +func newFindPreviousMenuItem() *MenuItem { + panic("Implement me") +} + +func newHelpMenuItem() *MenuItem { + panic("Implement me") +} diff --git a/v3/pkg/application/menuitem_production.go b/v3/pkg/application/menuitem_production.go index 387b9d06c..b5aac387f 100644 --- a/v3/pkg/application/menuitem_production.go +++ b/v3/pkg/application/menuitem_production.go @@ -2,6 +2,6 @@ package application -func newOpenDevToolsMenuItem() *MenuItem { +func NewOpenDevToolsMenuItem() *MenuItem { return nil } diff --git a/v3/pkg/application/menuitem_roles.go b/v3/pkg/application/menuitem_roles.go new file mode 100644 index 000000000..b1e8eb086 --- /dev/null +++ b/v3/pkg/application/menuitem_roles.go @@ -0,0 +1,290 @@ +package application + +import "runtime" + +func NewSpeechMenu() *MenuItem { + speechMenu := NewMenu() + speechMenu.AddRole(StartSpeaking) + speechMenu.AddRole(StopSpeaking) + subMenu := NewSubMenuItem("Speech") + subMenu.submenu = speechMenu + return subMenu +} + +func NewHideMenuItem() *MenuItem { + return NewMenuItem("Hide " + globalApplication.options.Name). + SetAccelerator("CmdOrCtrl+h"). + SetRole(Hide) +} + +func NewHideOthersMenuItem() *MenuItem { + return NewMenuItem("Hide Others"). + SetAccelerator("CmdOrCtrl+OptionOrAlt+h"). + SetRole(HideOthers) +} + +func NewFrontMenuItem() *MenuItem { + return NewMenuItem("Bring All to Front") +} + +func NewUnhideMenuItem() *MenuItem { + return NewMenuItem("Show All") +} + +func NewUndoMenuItem() *MenuItem { + return NewMenuItem("Undo"). + SetAccelerator("CmdOrCtrl+z") +} + +// newRedoMenuItem creates a new menu item for redoing the last action +func NewRedoMenuItem() *MenuItem { + return NewMenuItem("Redo"). + SetAccelerator("CmdOrCtrl+Shift+z") +} + +func NewCutMenuItem() *MenuItem { + return NewMenuItem("Cut"). + SetAccelerator("CmdOrCtrl+x") +} + +func NewCopyMenuItem() *MenuItem { + return NewMenuItem("Copy"). + SetAccelerator("CmdOrCtrl+c") +} + +func NewPasteMenuItem() *MenuItem { + return NewMenuItem("Paste"). + SetAccelerator("CmdOrCtrl+v") +} + +func NewPasteAndMatchStyleMenuItem() *MenuItem { + return NewMenuItem("Paste and Match Style"). + SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+v") +} + +func NewDeleteMenuItem() *MenuItem { + return NewMenuItem("Delete"). + SetAccelerator("backspace") +} + +func NewQuitMenuItem() *MenuItem { + label := "Quit" + if runtime.GOOS == "darwin" { + if globalApplication.options.Name != "" { + label += " " + globalApplication.options.Name + } + } + return NewMenuItem(label). + SetAccelerator("CmdOrCtrl+q"). + OnClick(func(ctx *Context) { + globalApplication.Quit() + }) +} + +func NewSelectAllMenuItem() *MenuItem { + return NewMenuItem("Select All"). + SetAccelerator("CmdOrCtrl+a") +} + +func NewAboutMenuItem() *MenuItem { + label := "About" + if globalApplication.options.Name != "" { + label += " " + globalApplication.options.Name + } + return NewMenuItem(label). + OnClick(func(ctx *Context) { + globalApplication.ShowAboutDialog() + }) +} + +func NewCloseMenuItem() *MenuItem { + return NewMenuItem("Close"). + SetAccelerator("CmdOrCtrl+w"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Close() + } + }) +} + +func NewReloadMenuItem() *MenuItem { + return NewMenuItem("Reload"). + SetAccelerator("CmdOrCtrl+r"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Reload() + } + }) +} + +func NewForceReloadMenuItem() *MenuItem { + return NewMenuItem("Force Reload"). + SetAccelerator("CmdOrCtrl+Shift+r"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.ForceReload() + } + }) +} + +func NewToggleFullscreenMenuItem() *MenuItem { + result := NewMenuItem("Toggle Full Screen"). + SetAccelerator("Ctrl+Command+F"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.ToggleFullscreen() + } + }) + if runtime.GOOS != "darwin" { + result.SetAccelerator("F11") + } + return result +} + +func NewZoomResetMenuItem() *MenuItem { + // reset zoom menu item + return NewMenuItem("Actual Size"). + SetAccelerator("CmdOrCtrl+0"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.ZoomReset() + } + }) +} + +func NewZoomInMenuItem() *MenuItem { + return NewMenuItem("Zoom In"). + SetAccelerator("CmdOrCtrl+plus"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.ZoomIn() + } + }) +} + +func NewZoomOutMenuItem() *MenuItem { + return NewMenuItem("Zoom Out"). + SetAccelerator("CmdOrCtrl+-"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.ZoomOut() + } + }) +} + +func NewMinimizeMenuItem() *MenuItem { + return NewMenuItem("Minimize"). + SetAccelerator("CmdOrCtrl+M"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Minimise() + } + }) +} + +func NewZoomMenuItem() *MenuItem { + return NewMenuItem("Zoom"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Zoom() + } + }) +} + +func NewFullScreenMenuItem() *MenuItem { + return NewMenuItem("Fullscreen"). + OnClick(func(ctx *Context) { + currentWindow := globalApplication.CurrentWindow() + if currentWindow != nil { + currentWindow.Fullscreen() + } + }) +} + +func NewPrintMenuItem() *MenuItem { + return NewMenuItem("Print"). + SetAccelerator("CmdOrCtrl+p") +} + +func NewPageLayoutMenuItem() *MenuItem { + return NewMenuItem("Page Setup..."). + SetAccelerator("CmdOrCtrl+Shift+p") +} + +func NewShowAllMenuItem() *MenuItem { + return NewMenuItem("Show All") +} + +func NewBringAllToFrontMenuItem() *MenuItem { + return NewMenuItem("Bring All to Front") +} + +func NewNewFileMenuItem() *MenuItem { + return NewMenuItem("New File"). + SetAccelerator("CmdOrCtrl+n") +} + +func NewOpenMenuItem() *MenuItem { + return NewMenuItem("Open..."). + SetAccelerator("CmdOrCtrl+o"). + SetRole(Open) +} + +func NewSaveMenuItem() *MenuItem { + return NewMenuItem("Save"). + SetAccelerator("CmdOrCtrl+s") +} + +func NewSaveAsMenuItem() *MenuItem { + return NewMenuItem("Save As..."). + SetAccelerator("CmdOrCtrl+Shift+s") +} + +func NewStartSpeakingMenuItem() *MenuItem { + return NewMenuItem("Start Speaking"). + SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+.") +} + +func NewStopSpeakingMenuItem() *MenuItem { + return NewMenuItem("Stop Speaking"). + SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+,") +} + +func NewRevertMenuItem() *MenuItem { + return NewMenuItem("Revert"). + SetAccelerator("CmdOrCtrl+r") +} + +func NewFindMenuItem() *MenuItem { + return NewMenuItem("Find..."). + SetAccelerator("CmdOrCtrl+f") +} + +func NewFindAndReplaceMenuItem() *MenuItem { + return NewMenuItem("Find and Replace..."). + SetAccelerator("CmdOrCtrl+Shift+f") +} + +func NewFindNextMenuItem() *MenuItem { + return NewMenuItem("Find Next"). + SetAccelerator("CmdOrCtrl+g") +} + +func NewFindPreviousMenuItem() *MenuItem { + return NewMenuItem("Find Previous"). + SetAccelerator("CmdOrCtrl+Shift+g") +} + +func NewHelpMenuItem() *MenuItem { + return NewMenuItem("Help"). + SetAccelerator("CmdOrCtrl+?") +} diff --git a/v3/pkg/application/menuitem_selectors_darwin.go b/v3/pkg/application/menuitem_selectors_darwin.go new file mode 100644 index 000000000..59b2ef5e2 --- /dev/null +++ b/v3/pkg/application/menuitem_selectors_darwin.go @@ -0,0 +1,58 @@ +// File: v3/pkg/application/menuitem_selectors_darwin.go + +//go:build darwin + +package application + +import "C" + +var roleToSelector = map[Role]string{ + //AppMenu: "", // This is a special case, handled separately + About: "orderFrontStandardAboutPanel:", + //ServicesMenu: "", // This is a submenu, no direct selector + Hide: "hide:", + HideOthers: "hideOtherApplications:", + ShowAll: "unhideAllApplications:", + Quit: "terminate:", + //WindowMenu: "", // This is a submenu, no direct selector + Minimize: "performMiniaturize:", + Zoom: "performZoom:", + BringAllToFront: "arrangeInFront:", + CloseWindow: "performClose:", + //EditMenu: "", // This is a submenu, no direct selector + Undo: "undo:", + Redo: "redo:", + Cut: "cut:", + Copy: "copy:", + Paste: "paste:", + Delete: "delete:", + SelectAll: "selectAll:", + //FindMenu: "", // This is a submenu, no direct selector + Find: "performTextFinderAction:", + FindAndReplace: "performTextFinderAction:", + FindNext: "performTextFinderAction:", + FindPrevious: "performTextFinderAction:", + UseSelectionForFind: "performTextFinderAction:", + //ViewMenu: "", // This is a submenu, no direct selector + ToggleFullscreen: "toggleFullScreen:", + //FileMenu: "", // This is a submenu, no direct selector + NewFile: "newDocument:", + Open: "openDocument:", + Save: "saveDocument:", + SaveAs: "saveDocumentAs:", + StartSpeaking: "startSpeaking:", + StopSpeaking: "stopSpeaking:", + Revert: "revertDocumentToSaved:", + Print: "printDocument:", + PageLayout: "runPageLayout:", + //HelpMenu: "", // This is a submenu, no direct selector + Help: "showHelp:", + //No: "", // No specific selector for this role +} + +func getSelectorForRole(role Role) *C.char { + if selector, ok := roleToSelector[role]; ok && selector != "" { + return C.CString(selector) + } + return nil +} diff --git a/v3/pkg/application/menuitem_windows.go b/v3/pkg/application/menuitem_windows.go index 8d9fdb0d0..bb9a70a2d 100644 --- a/v3/pkg/application/menuitem_windows.go +++ b/v3/pkg/application/menuitem_windows.go @@ -4,7 +4,6 @@ package application import ( "github.com/wailsapp/wails/v3/pkg/w32" - "runtime" "unsafe" ) @@ -135,192 +134,125 @@ func newMenuItemImpl(item *MenuItem, parentMenu w32.HMENU, ID int) *windowsMenuI return result } -func newSpeechMenu() *MenuItem { - panic("implement me") -} - -func newHideMenuItem() *MenuItem { - panic("implement me") - -} - -func newHideOthersMenuItem() *MenuItem { - panic("implement me") - -} - -func newUnhideMenuItem() *MenuItem { - panic("implement me") - -} - -func newUndoMenuItem() *MenuItem { - panic("implement me") - -} - -// newRedoMenuItem creates a new menu item for redoing the last action -func newRedoMenuItem() *MenuItem { - panic("implement me") - -} - -func newCutMenuItem() *MenuItem { - panic("implement me") - -} - -func newCopyMenuItem() *MenuItem { - panic("implement me") - -} - -func newPasteMenuItem() *MenuItem { - panic("implement me") - -} - -func newPasteAndMatchStyleMenuItem() *MenuItem { - panic("implement me") - -} - -func newDeleteMenuItem() *MenuItem { - panic("implement me") - -} - -func newQuitMenuItem() *MenuItem { - return NewMenuItem("Quit"). - OnClick(func(ctx *Context) { - globalApplication.Quit() - }) -} - -func newSelectAllMenuItem() *MenuItem { - panic("implement me") - -} - -func newAboutMenuItem() *MenuItem { - return NewMenuItem("About " + globalApplication.options.Name). - OnClick(func(ctx *Context) { - globalApplication.ShowAboutDialog() - }) -} - -func newCloseMenuItem() *MenuItem { - return NewMenuItem("Close"). - SetAccelerator("CmdOrCtrl+w"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Close() - } - }) -} -func newReloadMenuItem() *MenuItem { - return NewMenuItem("Reload"). - SetAccelerator("CmdOrCtrl+r"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Reload() - } - }) -} - -func newForceReloadMenuItem() *MenuItem { - return NewMenuItem("Force Reload"). - SetAccelerator("CmdOrCtrl+Shift+r"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ForceReload() - } - }) -} - -func newToggleFullscreenMenuItem() *MenuItem { - result := NewMenuItem("Toggle Full Screen"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ToggleFullscreen() - } - }) - if runtime.GOOS == "darwin" { - result.SetAccelerator("Ctrl+Command+F") - } else { - result.SetAccelerator("F11") - } - return result -} - -func newZoomResetMenuItem() *MenuItem { - // reset zoom menu item - return NewMenuItem("Actual Size"). - SetAccelerator("CmdOrCtrl+0"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomReset() - } - }) -} - -func newZoomInMenuItem() *MenuItem { - return NewMenuItem("Zoom In"). - SetAccelerator("CmdOrCtrl+plus"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomIn() - } - }) -} - -func newZoomOutMenuItem() *MenuItem { - return NewMenuItem("Zoom Out"). - SetAccelerator("CmdOrCtrl+-"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.ZoomOut() - } - }) -} - -func newFullScreenMenuItem() *MenuItem { - return NewMenuItem("Fullscreen"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Fullscreen() - } - }) -} - -func newMinimizeMenuItem() *MenuItem { - return NewMenuItem("Minimize"). - SetAccelerator("CmdOrCtrl+M"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Minimise() - } - }) -} - -func newZoomMenuItem() *MenuItem { - return NewMenuItem("Zoom"). - OnClick(func(ctx *Context) { - currentWindow := globalApplication.CurrentWindow() - if currentWindow != nil { - currentWindow.Zoom() - } - }) -} +//func newAboutMenuItem() *MenuItem { +// return NewMenuItem("About " + globalApplication.options.Name). +// OnClick(func(ctx *Context) { +// globalApplication.ShowAboutDialog() +// }) +//} +// +//func newCloseMenuItem() *MenuItem { +// return NewMenuItem("Close"). +// SetAccelerator("CmdOrCtrl+w"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.Close() +// } +// }) +//} +//func newReloadMenuItem() *MenuItem { +// return NewMenuItem("Reload"). +// SetAccelerator("CmdOrCtrl+r"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.Reload() +// } +// }) +//} +// +//func newForceReloadMenuItem() *MenuItem { +// return NewMenuItem("Force Reload"). +// SetAccelerator("CmdOrCtrl+Shift+r"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.ForceReload() +// } +// }) +//} +// +//func newToggleFullscreenMenuItem() *MenuItem { +// result := NewMenuItem("Toggle Full Screen"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.ToggleFullscreen() +// } +// }) +// if runtime.GOOS == "darwin" { +// result.SetAccelerator("Ctrl+Command+F") +// } else { +// result.SetAccelerator("F11") +// } +// return result +//} +// +//func newZoomResetMenuItem() *MenuItem { +// // reset zoom menu item +// return NewMenuItem("Actual Size"). +// SetAccelerator("CmdOrCtrl+0"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.ZoomReset() +// } +// }) +//} +// +//func newZoomInMenuItem() *MenuItem { +// return NewMenuItem("Zoom In"). +// SetAccelerator("CmdOrCtrl+plus"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.ZoomIn() +// } +// }) +//} +// +//func newZoomOutMenuItem() *MenuItem { +// return NewMenuItem("Zoom Out"). +// SetAccelerator("CmdOrCtrl+-"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.ZoomOut() +// } +// }) +//} +// +//func newFullScreenMenuItem() *MenuItem { +// return NewMenuItem("Fullscreen"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.Fullscreen() +// } +// }) +//} +// +//func newMinimizeMenuItem() *MenuItem { +// return NewMenuItem("Minimize"). +// SetAccelerator("CmdOrCtrl+M"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.Minimise() +// } +// }) +//} +// +//func newZoomMenuItem() *MenuItem { +// return NewMenuItem("Zoom"). +// OnClick(func(ctx *Context) { +// currentWindow := globalApplication.CurrentWindow() +// if currentWindow != nil { +// currentWindow.Zoom() +// } +// }) +//} // ---------- unsupported on windows ---------- diff --git a/v3/pkg/application/roles.go b/v3/pkg/application/roles.go index b5ab32923..4786c9862 100644 --- a/v3/pkg/application/roles.go +++ b/v3/pkg/application/roles.go @@ -20,6 +20,8 @@ const ( Hide Role = iota HideOthers Role = iota + ShowAll Role = iota + BringAllToFront Role = iota UnHide Role = iota About Role = iota Undo Role = iota @@ -33,7 +35,7 @@ const ( SpeechMenu Role = iota Quit Role = iota FileMenu Role = iota - Close Role = iota + CloseWindow Role = iota Reload Role = iota ForceReload Role = iota OpenDevTools Role = iota @@ -45,25 +47,28 @@ const ( Minimize Role = iota Zoom Role = iota FullScreen Role = iota - //Front Role = iota - //WindowRole Role = iota - //QuitRole Role = - //TogglefullscreenRole Role = "togglefullscreen" - //ViewMenuRole Role = "viewMenu" - //WindowMenuRole Role = "windowMenu" - - //FrontRole Role = "front" - //ZoomRole Role = "zoom" - //WindowSubMenuRole Role = "windowSubMenu" - //HelpSubMenuRole Role = "helpSubMenu" - //SeparatorItemRole Role = "separatorItem" + NewFile Role = iota + Open Role = iota + Save Role = iota + SaveAs Role = iota + StartSpeaking Role = iota + StopSpeaking Role = iota + Revert Role = iota + Print Role = iota + PageLayout Role = iota + Find Role = iota + FindAndReplace Role = iota + FindNext Role = iota + FindPrevious Role = iota + Front Role = iota + Help Role = iota ) -func newFileMenu() *MenuItem { +func NewFileMenu() *MenuItem { fileMenu := NewMenu() if runtime.GOOS == "darwin" { - fileMenu.AddRole(Close) + fileMenu.AddRole(CloseWindow) } else { fileMenu.AddRole(Quit) } @@ -72,7 +77,7 @@ func newFileMenu() *MenuItem { return subMenu } -func newViewMenu() *MenuItem { +func NewViewMenu() *MenuItem { viewMenu := NewMenu() viewMenu.AddRole(Reload) viewMenu.AddRole(ForceReload) @@ -88,7 +93,7 @@ func newViewMenu() *MenuItem { return subMenu } -func newAppMenu() *MenuItem { +func NewAppMenu() *MenuItem { if runtime.GOOS != "darwin" { return nil } @@ -107,7 +112,7 @@ func newAppMenu() *MenuItem { return subMenu } -func newEditMenu() *MenuItem { +func NewEditMenu() *MenuItem { editMenu := NewMenu() editMenu.AddRole(Undo) editMenu.AddRole(Redo) @@ -132,22 +137,24 @@ func newEditMenu() *MenuItem { return subMenu } -func newWindowMenu() *MenuItem { +func NewWindowMenu() *MenuItem { menu := NewMenu() menu.AddRole(Minimize) menu.AddRole(Zoom) if runtime.GOOS == "darwin" { menu.AddSeparator() - menu.AddRole(FullScreen) + menu.AddRole(Front) + //menu.AddSeparator() + //menu.AddRole(Window) } else { - menu.AddRole(Close) + menu.AddRole(CloseWindow) } subMenu := NewSubMenuItem("Window") subMenu.submenu = menu return subMenu } -func newHelpMenu() *MenuItem { +func NewHelpMenu() *MenuItem { menu := NewMenu() menu.Add("Learn More").OnClick(func(ctx *Context) { globalApplication.CurrentWindow().SetURL("https://wails.io") diff --git a/v3/pkg/w32/actions.go b/v3/pkg/w32/actions.go new file mode 100644 index 000000000..35a06e88f --- /dev/null +++ b/v3/pkg/w32/actions.go @@ -0,0 +1,25 @@ +package w32 + +func Undo(hwnd HWND) { + SendMessage(hwnd, WM_UNDO, 0, 0) +} + +func Cut(hwnd HWND) { + SendMessage(hwnd, WM_CUT, 0, 0) +} + +func Copy(hwnd HWND) { + SendMessage(hwnd, WM_COPY, 0, 0) +} + +func Paste(hwnd HWND) { + SendMessage(hwnd, WM_PASTE, 0, 0) +} + +func Delete(hwnd HWND) { + SendMessage(hwnd, WM_CLEAR, 0, 0) +} + +func SelectAll(hwnd HWND) { + SendMessage(hwnd, WM_SELECTALL, 0, 0) +} diff --git a/v3/pkg/w32/constants.go b/v3/pkg/w32/constants.go index f6cab85c8..254c4937f 100644 --- a/v3/pkg/w32/constants.go +++ b/v3/pkg/w32/constants.go @@ -538,6 +538,7 @@ const ( WM_VSCROLLCLIPBOARD = 778 WM_WINDOWPOSCHANGED = 71 WM_WINDOWPOSCHANGING = 70 + WM_SELECTALL = 0x00B1 WM_WININICHANGE = 26 WM_KEYFIRST = 256 WM_KEYLAST = 264