diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index ad89d408b..bc284f3a0 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -146,7 +146,7 @@ type ( } runnable interface { - run() + Run() } ) @@ -219,7 +219,7 @@ type App struct { applicationEventHooksLock sync.RWMutex // Windows - windows map[uint]*WebviewWindow + windows map[uint]Window windowsLock sync.Mutex // System Trays @@ -257,7 +257,7 @@ type App struct { startURL string // Hooks - windowCreatedCallbacks []func(window *WebviewWindow) + windowCreatedCallbacks []func(window Window) pid int // Capabilities @@ -270,7 +270,7 @@ type App struct { func (a *App) init() { a.applicationEventListeners = make(map[uint][]*EventListener) - a.windows = make(map[uint]*WebviewWindow) + a.windows = make(map[uint]Window) a.systemTrays = make(map[uint]*SystemTray) a.contextMenus = make(map[string]*Menu) a.keyBindings = make(map[string]func(window *WebviewWindow)) @@ -285,7 +285,7 @@ func (a *App) getSystemTrayID() uint { return a.systemTrayID } -func (a *App) getWindowForID(id uint) *WebviewWindow { +func (a *App) getWindowForID(id uint) Window { a.windowsLock.Lock() defer a.windowsLock.Unlock() return a.windows[id] @@ -340,7 +340,7 @@ func (a *App) RegisterHook(eventType events.ApplicationEventType, callback func( } } -func (a *App) NewWebviewWindow() *WebviewWindow { +func (a *App) NewWebviewWindow() Window { return a.NewWebviewWindowWithOptions(WebviewWindowOptions{}) } @@ -376,9 +376,9 @@ func (a *App) error(message string, args ...any) { } } -func (a *App) NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) *WebviewWindow { - newWindow := newWindow(windowOptions) - id := newWindow.id +func (a *App) NewWebviewWindowWithOptions(windowOptions WebviewWindowOptions) Window { + newWindow := NewWindow(windowOptions) + id := newWindow.ID() a.windowsLock.Lock() a.windows[id] = newWindow @@ -460,8 +460,13 @@ func (a *App) Run() error { a.runLock.Lock() a.running = true + // run windows + for _, window := range a.windows { + go window.Run() + } + for _, systray := range a.pendingRun { - go systray.run() + go systray.Run() } a.pendingRun = nil @@ -519,7 +524,7 @@ func (a *App) handleDragAndDropMessage(event *dragAndDropMessage) { return } // Get callback from window - window.handleDragAndDropMessage(event) + window.HandleDragAndDropMessage(event.filenames) } func (a *App) handleWindowMessage(event *windowMessage) { @@ -532,7 +537,7 @@ func (a *App) handleWindowMessage(event *windowMessage) { return } // Get callback from window - window.handleMessage(event.message) + window.HandleMessage(event.message) } func (a *App) handleWebViewRequest(request *webViewAssetRequest) { @@ -545,10 +550,10 @@ func (a *App) handleWindowEvent(event *windowEvent) { window, ok := a.windows[event.WindowID] a.windowsLock.Unlock() if !ok { - log.Printf("WebviewWindow #%d not found", event.WindowID) + log.Printf("Window #%d not found", event.WindowID) return } - window.handleWindowEvent(event.EventID) + window.HandleWindowEvent(event.EventID) } func (a *App) handleMenuItemClicked(menuItemID uint) { @@ -560,7 +565,7 @@ func (a *App) handleMenuItemClicked(menuItemID uint) { menuItem.handleClick() } -func (a *App) CurrentWindow() *WebviewWindow { +func (a *App) CurrentWindow() Window { if a.impl == nil { return nil } @@ -672,7 +677,7 @@ func SaveFileDialogWithOptions(s *SaveFileDialogOptions) *SaveFileDialogStruct { func (a *App) dispatchEventToWindows(event *WailsEvent) { for _, window := range a.windows { - window.dispatchWailsEvent(event) + window.DispatchWailsEvent(event) } } @@ -709,11 +714,11 @@ func (a *App) getContextMenu(name string) (*Menu, bool) { } -func (a *App) OnWindowCreation(callback func(window *WebviewWindow)) { +func (a *App) OnWindowCreation(callback func(window Window)) { a.windowCreatedCallbacks = append(a.windowCreatedCallbacks, callback) } -func (a *App) GetWindowByName(name string) *WebviewWindow { +func (a *App) GetWindowByName(name string) Window { a.windowsLock.Lock() defer a.windowsLock.Unlock() for _, window := range a.windows { @@ -733,7 +738,7 @@ func (a *App) runOrDeferToAppRun(r runnable) { a.runLock.Unlock() if running { - r.run() + r.Run() } } @@ -765,5 +770,26 @@ func (a *App) handleWindowKeyEvent(event *windowKeyEvent) { return } // Get callback from window - window.handleKeyEvent(event.acceleratorString) + window.HandleKeyEvent(event.acceleratorString) +} + +func (a *App) AssetServerHandler() func(rw http.ResponseWriter, req *http.Request) { + return a.assets.ServeHTTP +} + +func (a *App) RegisterWindow(window Window) uint { + id := getWindowID() + if a.windows == nil { + a.windows = make(map[uint]Window) + } + a.windowsLock.Lock() + defer a.windowsLock.Unlock() + a.windows[id] = window + return id +} + +func (a *App) UnregisterWindow(id uint) { + a.windowsLock.Lock() + defer a.windowsLock.Unlock() + delete(a.windows, id) } diff --git a/v3/pkg/application/bindings.go b/v3/pkg/application/bindings.go index 1e81ccb86..5dd2b47b7 100644 --- a/v3/pkg/application/bindings.go +++ b/v3/pkg/application/bindings.go @@ -2,11 +2,12 @@ package application import ( "fmt" - "github.com/wailsapp/wails/v3/internal/hash" "reflect" "runtime" "strings" + "github.com/wailsapp/wails/v3/internal/hash" + "github.com/samber/lo" ) diff --git a/v3/pkg/application/dialogs.go b/v3/pkg/application/dialogs.go index 52a034c54..6668a0c9b 100644 --- a/v3/pkg/application/dialogs.go +++ b/v3/pkg/application/dialogs.go @@ -76,7 +76,7 @@ type MessageDialogOptions struct { Message string Buttons []*Button Icon []byte - window *WebviewWindow + window Window } type MessageDialog struct { @@ -132,7 +132,7 @@ func (d *MessageDialog) AddButtons(buttons []*Button) *MessageDialog { return d } -func (d *MessageDialog) AttachToWindow(window *WebviewWindow) *MessageDialog { +func (d *MessageDialog) AttachToWindow(window Window) *MessageDialog { d.window = window return d } @@ -179,7 +179,7 @@ type OpenFileDialogOptions struct { TreatsFilePackagesAsDirectories bool AllowsOtherFileTypes bool Filters []FileFilter - Window *WebviewWindow + Window Window Title string Message string @@ -205,7 +205,7 @@ type OpenFileDialogStruct struct { message string buttonText string directory string - window *WebviewWindow + window Window impl openFileDialogImpl } @@ -245,7 +245,7 @@ func (d *OpenFileDialogStruct) TreatsFilePackagesAsDirectories(treatsFilePackage return d } -func (d *OpenFileDialogStruct) AttachToWindow(window *WebviewWindow) *OpenFileDialogStruct { +func (d *OpenFileDialogStruct) AttachToWindow(window Window) *OpenFileDialogStruct { d.window = window return d } @@ -361,7 +361,7 @@ type SaveFileDialogOptions struct { Filename string ButtonText string Filters []FileFilter - Window *WebviewWindow + Window Window } type SaveFileDialogStruct struct { @@ -378,7 +378,7 @@ type SaveFileDialogStruct struct { buttonText string filters []FileFilter - window *WebviewWindow + window Window impl saveFileDialogImpl title string @@ -439,7 +439,7 @@ func (d *SaveFileDialogStruct) SetDirectory(directory string) *SaveFileDialogStr return d } -func (d *SaveFileDialogStruct) AttachToWindow(window *WebviewWindow) *SaveFileDialogStruct { +func (d *SaveFileDialogStruct) AttachToWindow(window Window) *SaveFileDialogStruct { d.window = window return d } diff --git a/v3/pkg/application/dialogs_linux.go b/v3/pkg/application/dialogs_linux.go index db8e21e34..f1147830d 100644 --- a/v3/pkg/application/dialogs_linux.go +++ b/v3/pkg/application/dialogs_linux.go @@ -4,7 +4,7 @@ func (m *linuxApp) showAboutDialog(title string, message string, icon []byte) { window := globalApplication.getWindowForID(m.getCurrentWindowID()) var parent pointer if window != nil { - parent = window.impl.(*linuxWebviewWindow).window + parent = (window.(*WebviewWindow).impl).(*linuxWebviewWindow).window } about := newMessageDialog(InfoDialogType) about.SetTitle(title). @@ -25,7 +25,7 @@ func (m *linuxDialog) show() { window := globalApplication.getWindowForID(windowId) var parent pointer if window != nil { - parent = window.impl.(*linuxWebviewWindow).window + parent = (window.(*WebviewWindow).impl).(*linuxWebviewWindow).window } response := runQuestionDialog(parent, m.dialog) diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go index a86f20904..b389d99d6 100644 --- a/v3/pkg/application/linux_cgo.go +++ b/v3/pkg/application/linux_cgo.go @@ -762,7 +762,10 @@ func windowSetURL(webview pointer, uri string) { func emit(we *C.WindowEvent) { window := globalApplication.getWindowForID(uint(we.id)) if window != nil { - window.emit(events.WindowEventType(we.event)) + windowEvents <- &windowEvent{ + WindowID: window.ID(), + EventID: uint(events.WindowEventType(we.event)), + } } } @@ -846,7 +849,7 @@ func onButtonEvent(_ *C.GtkWidget, event *C.GdkEventButton, data unsafe.Pointer) if window == nil { return C.gboolean(0) } - lw, ok := (window.impl).(*linuxWebviewWindow) + lw, ok := (window.(*WebviewWindow).impl).(*linuxWebviewWindow) if !ok { return C.gboolean(0) } @@ -1031,7 +1034,7 @@ func runOpenFileDialog(dialog *OpenFileDialogStruct) ([]string, error) { window := nilPointer if dialog.window != nil { - window = (dialog.window.impl).(*linuxWebviewWindow).window + window = (dialog.window.(*WebviewWindow).impl).(*linuxWebviewWindow).window } buttonText := dialog.buttonText diff --git a/v3/pkg/application/linux_purego.go b/v3/pkg/application/linux_purego.go index e0303afff..682bf195e 100644 --- a/v3/pkg/application/linux_purego.go +++ b/v3/pkg/application/linux_purego.go @@ -1087,7 +1087,7 @@ func runOpenFileDialog(dialog *OpenFileDialogStruct) ([]string, error) { window := pointer(0) if dialog.window != nil { - window = (dialog.window.impl).(*linuxWebviewWindow).window + window = (dialog.window.(*WebviewWindow).impl).(*linuxWebviewWindow).window } buttonText := dialog.buttonText diff --git a/v3/pkg/application/messageprocessor.go b/v3/pkg/application/messageprocessor.go index f5fb9b729..6b49dbdb7 100644 --- a/v3/pkg/application/messageprocessor.go +++ b/v3/pkg/application/messageprocessor.go @@ -40,7 +40,7 @@ func (m *MessageProcessor) httpError(rw http.ResponseWriter, message string, arg rw.Write([]byte(fmt.Sprintf(message, args...))) } -func (m *MessageProcessor) getTargetWindow(r *http.Request) *WebviewWindow { +func (m *MessageProcessor) getTargetWindow(r *http.Request) Window { windowName := r.Header.Get(webViewRequestHeaderWindowName) if windowName != "" { return globalApplication.GetWindowByName(windowName) diff --git a/v3/pkg/application/messageprocessor_application.go b/v3/pkg/application/messageprocessor_application.go index d54570bb2..fae7b55a6 100644 --- a/v3/pkg/application/messageprocessor_application.go +++ b/v3/pkg/application/messageprocessor_application.go @@ -16,8 +16,7 @@ var applicationMethodNames = map[int]string{ ApplicationShow: "Show", } -func (m *MessageProcessor) processApplicationMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) { - +func (m *MessageProcessor) processApplicationMethod(method int, rw http.ResponseWriter, r *http.Request, window Window, params QueryParams) { switch method { case ApplicationQuit: globalApplication.Quit() diff --git a/v3/pkg/application/messageprocessor_call.go b/v3/pkg/application/messageprocessor_call.go index 4dd3b41b4..6fe7965de 100644 --- a/v3/pkg/application/messageprocessor_call.go +++ b/v3/pkg/application/messageprocessor_call.go @@ -4,31 +4,29 @@ import ( "encoding/json" "fmt" "net/http" - "strconv" ) const ( CallBinding = 0 ) -func (m *MessageProcessor) callErrorCallback(window *WebviewWindow, message string, callID *string, err error) { +func (m *MessageProcessor) callErrorCallback(window Window, message string, callID *string, err error) { errorMsg := fmt.Sprintf(message, err) m.Error(errorMsg) - msg := "_wails.callErrorCallback('" + *callID + "', " + strconv.Quote(errorMsg) + ");" - window.ExecJS(msg) + window.CallError(*callID, errorMsg) } -func (m *MessageProcessor) callCallback(window *WebviewWindow, callID *string, result string, isJSON bool) { - msg := fmt.Sprintf("_wails.callCallback('%s', %s, %v);", *callID, strconv.Quote(result), isJSON) - window.ExecJS(msg) +func (m *MessageProcessor) callCallback(window Window, callID *string, result string, isJSON bool) { + window.CallResponse(*callID, result) } -func (m *MessageProcessor) processCallMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processCallMethod(method int, rw http.ResponseWriter, r *http.Request, window Window, params QueryParams) { args, err := params.Args() if err != nil { m.httpError(rw, "Unable to parse arguments: %s", err.Error()) return } + fmt.Println("processCallMethod", args) callID := args.String("call-id") if callID == nil { m.Error("call-id is required") diff --git a/v3/pkg/application/messageprocessor_clipboard.go b/v3/pkg/application/messageprocessor_clipboard.go index 7aae8e7ec..8ba3b35d9 100644 --- a/v3/pkg/application/messageprocessor_clipboard.go +++ b/v3/pkg/application/messageprocessor_clipboard.go @@ -14,7 +14,7 @@ var clipboardMethods = map[int]string{ ClipboardText: "Text", } -func (m *MessageProcessor) processClipboardMethod(method int, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processClipboardMethod(method int, rw http.ResponseWriter, _ *http.Request, _ Window, params QueryParams) { args, err := params.Args() if err != nil { diff --git a/v3/pkg/application/messageprocessor_contextmenu.go b/v3/pkg/application/messageprocessor_contextmenu.go index 30e8c05c3..8b655d0eb 100644 --- a/v3/pkg/application/messageprocessor_contextmenu.go +++ b/v3/pkg/application/messageprocessor_contextmenu.go @@ -19,7 +19,7 @@ var contextmenuMethodNames = map[int]string{ ContextMenuOpen: "Open", } -func (m *MessageProcessor) processContextMenuMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processContextMenuMethod(method int, rw http.ResponseWriter, _ *http.Request, window Window, params QueryParams) { switch method { case ContextMenuOpen: @@ -29,7 +29,7 @@ func (m *MessageProcessor) processContextMenuMethod(method int, rw http.Response m.httpError(rw, "error parsing contextmenu message: %s", err.Error()) return } - window.openContextMenu(&data) + window.OpenContextMenu(&data) m.ok(rw) default: m.httpError(rw, "Unknown contextmenu method: %d", method) diff --git a/v3/pkg/application/messageprocessor_dialog.go b/v3/pkg/application/messageprocessor_dialog.go index 7f8314880..38ab484e5 100644 --- a/v3/pkg/application/messageprocessor_dialog.go +++ b/v3/pkg/application/messageprocessor_dialog.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" "runtime" - "strconv" ) const ( @@ -26,20 +25,17 @@ var dialogMethodNames = map[int]string{ DialogSaveFile: "SaveFile", } -func (m *MessageProcessor) dialogErrorCallback(window *WebviewWindow, message string, dialogID *string, err error) { +func (m *MessageProcessor) dialogErrorCallback(window Window, message string, dialogID *string, err error) { errorMsg := fmt.Sprintf(message, err) m.Error(errorMsg) - msg := "_wails.dialogErrorCallback('" + *dialogID + "', " + strconv.Quote(errorMsg) + ");" - window.ExecJS(msg) - m.Error(message, "error", err) + window.DialogError(*dialogID, errorMsg) } -func (m *MessageProcessor) dialogCallback(window *WebviewWindow, dialogID *string, result string, isJSON bool) { - msg := fmt.Sprintf("_wails.dialogCallback('%s', %s, %v);", *dialogID, strconv.Quote(result), isJSON) - window.ExecJS(msg) +func (m *MessageProcessor) dialogCallback(window Window, dialogID *string, result string, isJSON bool) { + window.DialogResponse(*dialogID, result) } -func (m *MessageProcessor) processDialogMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processDialogMethod(method int, rw http.ResponseWriter, r *http.Request, window Window, params QueryParams) { args, err := params.Args() if err != nil { diff --git a/v3/pkg/application/messageprocessor_events.go b/v3/pkg/application/messageprocessor_events.go index cebc9ff83..d4758addb 100644 --- a/v3/pkg/application/messageprocessor_events.go +++ b/v3/pkg/application/messageprocessor_events.go @@ -12,7 +12,7 @@ var eventsMethodNames = map[int]string{ EventsEmit: "Emit", } -func (m *MessageProcessor) processEventsMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processEventsMethod(method int, rw http.ResponseWriter, _ *http.Request, window Window, params QueryParams) { var event WailsEvent diff --git a/v3/pkg/application/messageprocessor_screens.go b/v3/pkg/application/messageprocessor_screens.go index e178d22b2..4d379a5cb 100644 --- a/v3/pkg/application/messageprocessor_screens.go +++ b/v3/pkg/application/messageprocessor_screens.go @@ -16,7 +16,7 @@ var screensMethodNames = map[int]string{ ScreensGetCurrent: "GetCurrent", } -func (m *MessageProcessor) processScreensMethod(method int, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, _ QueryParams) { +func (m *MessageProcessor) processScreensMethod(method int, rw http.ResponseWriter, _ *http.Request, _ Window, _ QueryParams) { switch method { case ScreensGetAll: diff --git a/v3/pkg/application/messageprocessor_system.go b/v3/pkg/application/messageprocessor_system.go index c94b9ff17..fcd44a1a4 100644 --- a/v3/pkg/application/messageprocessor_system.go +++ b/v3/pkg/application/messageprocessor_system.go @@ -12,7 +12,7 @@ var systemMethodNames = map[int]string{ SystemIsDarkMode: "IsDarkMode", } -func (m *MessageProcessor) processSystemMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processSystemMethod(method int, rw http.ResponseWriter, r *http.Request, window Window, params QueryParams) { switch method { case SystemIsDarkMode: diff --git a/v3/pkg/application/messageprocessor_window.go b/v3/pkg/application/messageprocessor_window.go index 9d06e2789..d5463c35f 100644 --- a/v3/pkg/application/messageprocessor_window.go +++ b/v3/pkg/application/messageprocessor_window.go @@ -70,7 +70,7 @@ var windowMethodNames = map[int]string{ WindowSetZoomLevel: "SetZoomLevel", } -func (m *MessageProcessor) processWindowMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) { +func (m *MessageProcessor) processWindowMethod(method int, rw http.ResponseWriter, _ *http.Request, window Window, params QueryParams) { args, err := params.Args() if err != nil { diff --git a/v3/pkg/application/systemtray.go b/v3/pkg/application/systemtray.go index 0dc81836d..052c930f5 100644 --- a/v3/pkg/application/systemtray.go +++ b/v3/pkg/application/systemtray.go @@ -94,7 +94,7 @@ func (s *SystemTray) Label() string { return s.label } -func (s *SystemTray) run() { +func (s *SystemTray) Run() { s.impl = newSystemTrayImpl(s) if s.attachedWindow.Window != nil { diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 7af9e3222..8d10147e5 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -1,6 +1,7 @@ package application import ( + "encoding/json" "errors" "fmt" "runtime" @@ -125,6 +126,7 @@ func getWindowID() uint { return windowID } +// FIXME: This should like be an interface method (TDM) // Use onApplicationEvent to register a callback for an application event from a window. // This will handle tidying up the callback when the window is destroyed func (w *WebviewWindow) onApplicationEvent(eventType events.ApplicationEventType, callback func(*Event)) { @@ -156,8 +158,8 @@ func (w *WebviewWindow) setupEventMapping() { } } -// newWindow creates a new window with the given options -func newWindow(options WebviewWindowOptions) *WebviewWindow { +// NewWindow creates a new window with the given options +func NewWindow(options WebviewWindowOptions) Window { if options.Width == 0 { options.Width = 800 } @@ -219,8 +221,45 @@ func (w *WebviewWindow) addCancellationFunction(canceller func()) { w.cancellers = append(w.cancellers, canceller) } +// formatJS ensures the 'data' provided marshals to valid json or panics +func (w *WebviewWindow) formatJS(f string, callID string, data string) string { + j, err := json.Marshal(data) + if err != nil { + panic(err) + } + return fmt.Sprintf(f, callID, j) +} + +func (w *WebviewWindow) CallError(callID string, result string) { + if w.impl != nil { + w.impl.execJS(w.formatJS("_wails.callErrorCallback('%s', %s);", callID, result)) + } +} + +func (w *WebviewWindow) CallResponse(callID string, result string) { + if w.impl != nil { + w.impl.execJS(w.formatJS("_wails.callCallback('%s', %s, true);", callID, result)) + } +} + +func (w *WebviewWindow) DialogError(dialogID string, result string) { + if w.impl != nil { + w.impl.execJS(w.formatJS("_wails.dialogErrorCallback('%s', %s);", dialogID, result)) + } +} + +func (w *WebviewWindow) DialogResponse(dialogID string, result string) { + if w.impl != nil { + w.impl.execJS(w.formatJS("_wails.dialogCallback('%s', %s, true);", dialogID, result)) + } +} + +func (w *WebviewWindow) ID() uint { + return w.id +} + // SetTitle sets the title of the window -func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { +func (w *WebviewWindow) SetTitle(title string) Window { w.options.Title = title if w.impl != nil { InvokeSync(func() { @@ -236,7 +275,7 @@ func (w *WebviewWindow) Name() string { } // SetSize sets the size of the window -func (w *WebviewWindow) SetSize(width, height int) *WebviewWindow { +func (w *WebviewWindow) SetSize(width, height int) Window { // Don't set size if fullscreen if w.IsFullscreen() { return w @@ -278,7 +317,7 @@ func (w *WebviewWindow) SetSize(width, height int) *WebviewWindow { return w } -func (w *WebviewWindow) run() { +func (w *WebviewWindow) Run() { if w.impl != nil { return } @@ -287,7 +326,7 @@ func (w *WebviewWindow) run() { } // SetAlwaysOnTop sets the window to be always on top. -func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { +func (w *WebviewWindow) SetAlwaysOnTop(b bool) Window { w.options.AlwaysOnTop = b if w.impl != nil { InvokeSync(func() { @@ -298,12 +337,12 @@ func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { } // Show shows the window. -func (w *WebviewWindow) Show() *WebviewWindow { +func (w *WebviewWindow) Show() Window { if globalApplication.impl == nil { return w } if w.impl == nil { - InvokeSync(w.run) + InvokeSync(w.Run) return w } InvokeSync(w.impl.show) @@ -312,7 +351,7 @@ func (w *WebviewWindow) Show() *WebviewWindow { } // Hide hides the window. -func (w *WebviewWindow) Hide() *WebviewWindow { +func (w *WebviewWindow) Hide() Window { w.options.Hidden = true if w.impl != nil { InvokeSync(w.impl.hide) @@ -321,7 +360,7 @@ func (w *WebviewWindow) Hide() *WebviewWindow { return w } -func (w *WebviewWindow) SetURL(s string) *WebviewWindow { +func (w *WebviewWindow) SetURL(s string) Window { w.options.URL = s if w.impl != nil { InvokeSync(func() { @@ -332,7 +371,7 @@ func (w *WebviewWindow) SetURL(s string) *WebviewWindow { } // SetZoom sets the zoom level of the window. -func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { +func (w *WebviewWindow) SetZoom(magnification float64) Window { w.options.Zoom = magnification if w.impl != nil { InvokeSync(func() { @@ -351,7 +390,7 @@ func (w *WebviewWindow) GetZoom() float64 { } // SetResizable sets whether the window is resizable. -func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { +func (w *WebviewWindow) SetResizable(b bool) Window { w.options.DisableResize = !b if w.impl != nil { InvokeSync(func() { @@ -367,7 +406,7 @@ func (w *WebviewWindow) Resizable() bool { } // SetMinSize sets the minimum size of the window. -func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { +func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) Window { w.options.MinWidth = minWidth w.options.MinHeight = minHeight @@ -399,7 +438,7 @@ func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { } // SetMaxSize sets the maximum size of the window. -func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { +func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) Window { w.options.MaxWidth = maxWidth w.options.MaxHeight = maxHeight @@ -431,7 +470,7 @@ func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { } // ExecJS executes the given javascript in the context of the window. -func (w *WebviewWindow) ExecJS(js string) { +func (w *WebviewWindow) ExecJS(_callID, js string) { if w.impl == nil { return } @@ -439,19 +478,19 @@ func (w *WebviewWindow) ExecJS(js string) { } // Fullscreen sets the window to fullscreen mode. Min/Max size constraints are disabled. -func (w *WebviewWindow) Fullscreen() *WebviewWindow { +func (w *WebviewWindow) Fullscreen() Window { if w.impl == nil { w.options.StartState = WindowStateFullscreen return w } if !w.IsFullscreen() { - w.disableSizeConstraints() + w.DisableSizeConstraints() InvokeSync(w.impl.fullscreen) } return w } -func (w *WebviewWindow) SetFullscreenButtonEnabled(enabled bool) *WebviewWindow { +func (w *WebviewWindow) SetFullscreenButtonEnabled(enabled bool) Window { w.options.FullscreenButtonEnabled = enabled if w.impl != nil { InvokeSync(func() { @@ -524,7 +563,7 @@ func (w *WebviewWindow) IsFullscreen() bool { } // SetBackgroundColour sets the background colour of the window -func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { +func (w *WebviewWindow) SetBackgroundColour(colour RGBA) Window { w.options.BackgroundColour = colour if w.impl != nil { InvokeSync(func() { @@ -534,37 +573,32 @@ func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { return w } -func (w *WebviewWindow) handleMessage(message string) { +func (w *WebviewWindow) HandleMessage(message string) { // Check for special messages if message == "drag" { if !w.IsFullscreen() { InvokeSync(func() { err := w.startDrag() if err != nil { - w.error("Failed to start drag: %s", err) + w.Error("Failed to start drag: %s", err) } }) } - return } - if strings.HasPrefix(message, "resize:") { if !w.IsFullscreen() { sl := strings.Split(message, ":") if len(sl) != 2 { - w.error("Unknown message returned from dispatcher: %+v", message) + w.Error("Unknown message returned from dispatcher: %+v", message) return } err := w.startResize(sl[1]) if err != nil { - w.error(err.Error()) + w.Error(err.Error()) } } return } - - w.info("ProcessMessage from front end: %s", message) - } func (w *WebviewWindow) startResize(border string) error { @@ -622,7 +656,7 @@ func (w *WebviewWindow) RegisterHook(eventType events.WindowEventType, callback } } -func (w *WebviewWindow) handleWindowEvent(id uint) { +func (w *WebviewWindow) HandleWindowEvent(id uint) { w.eventListenersLock.RLock() defer w.eventListenersLock.RUnlock() @@ -738,7 +772,7 @@ func (w *WebviewWindow) ToggleDevTools() { } // ZoomReset resets the zoom level of the webview content to 100% -func (w *WebviewWindow) ZoomReset() *WebviewWindow { +func (w *WebviewWindow) ZoomReset() Window { if w.impl != nil { InvokeSync(w.impl.zoomReset) w.emit(events.Common.WindowZoomReset) @@ -783,7 +817,7 @@ func (w *WebviewWindow) Zoom() { } // SetHTML sets the HTML of the window to the given html string. -func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { +func (w *WebviewWindow) SetHTML(html string) Window { w.options.HTML = html if w.impl != nil { InvokeSync(func() { @@ -794,7 +828,7 @@ func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { } // SetRelativePosition sets the position of the window. -func (w *WebviewWindow) SetRelativePosition(x, y int) *WebviewWindow { +func (w *WebviewWindow) SetRelativePosition(x, y int) Window { w.options.X = x w.options.Y = y if w.impl != nil { @@ -806,7 +840,7 @@ func (w *WebviewWindow) SetRelativePosition(x, y int) *WebviewWindow { } // Minimise minimises the window. -func (w *WebviewWindow) Minimise() *WebviewWindow { +func (w *WebviewWindow) Minimise() Window { if w.impl == nil { w.options.StartState = WindowStateMinimised return w @@ -819,13 +853,13 @@ func (w *WebviewWindow) Minimise() *WebviewWindow { } // Maximise maximises the window. Min/Max size constraints are disabled. -func (w *WebviewWindow) Maximise() *WebviewWindow { +func (w *WebviewWindow) Maximise() Window { if w.impl == nil { w.options.StartState = WindowStateMaximised return w } if !w.IsMaximised() { - w.disableSizeConstraints() + w.DisableSizeConstraints() InvokeSync(w.impl.maximise) w.emit(events.Common.WindowMaximise) } @@ -849,7 +883,7 @@ func (w *WebviewWindow) UnMaximise() { return } if w.IsMaximised() { - w.enableSizeConstraints() + w.EnableSizeConstraints() InvokeSync(w.impl.unmaximise) w.emit(events.Common.WindowUnMaximise) } @@ -861,7 +895,7 @@ func (w *WebviewWindow) UnFullscreen() { return } if w.IsFullscreen() { - w.enableSizeConstraints() + w.EnableSizeConstraints() InvokeSync(w.impl.unfullscreen) w.emit(events.Common.WindowUnFullscreen) } @@ -884,7 +918,7 @@ func (w *WebviewWindow) Restore() { }) } -func (w *WebviewWindow) disableSizeConstraints() { +func (w *WebviewWindow) DisableSizeConstraints() { if w.impl == nil { return } @@ -898,7 +932,7 @@ func (w *WebviewWindow) disableSizeConstraints() { }) } -func (w *WebviewWindow) enableSizeConstraints() { +func (w *WebviewWindow) EnableSizeConstraints() { if w.impl == nil { return } @@ -921,7 +955,7 @@ func (w *WebviewWindow) GetScreen() (*Screen, error) { } // SetFrameless removes the window frame and title bar -func (w *WebviewWindow) SetFrameless(frameless bool) *WebviewWindow { +func (w *WebviewWindow) SetFrameless(frameless bool) Window { w.options.Frameless = frameless if w.impl != nil { InvokeSync(func() { @@ -931,9 +965,9 @@ func (w *WebviewWindow) SetFrameless(frameless bool) *WebviewWindow { return w } -func (w *WebviewWindow) dispatchWailsEvent(event *WailsEvent) { - msg := fmt.Sprintf("_wails.dispatchWailsEvent(%s);", event.toJSON()) - w.ExecJS(msg) +func (w *WebviewWindow) DispatchWailsEvent(event *WailsEvent) { + msg := fmt.Sprintf("_wails.dispatchWailsEvent(%s);", event.ToJSON()) + w.ExecJS("", msg) } func (w *WebviewWindow) dispatchWindowEvent(id uint) { @@ -942,40 +976,40 @@ func (w *WebviewWindow) dispatchWindowEvent(id uint) { jsEvent := &WailsEvent{ Name: events.JSEvent(id), } - w.dispatchWailsEvent(jsEvent) + w.DispatchWailsEvent(jsEvent) } -func (w *WebviewWindow) info(message string, args ...any) { +func (w *WebviewWindow) Info(message string, args ...any) { var messageArgs []interface{} messageArgs = append(messageArgs, args...) messageArgs = append(messageArgs, "sender", w.Name()) globalApplication.info(message, messageArgs...) } -func (w *WebviewWindow) error(message string, args ...any) { +func (w *WebviewWindow) Error(message string, args ...any) { var messageArgs []interface{} messageArgs = append(messageArgs, args...) messageArgs = append(messageArgs, "sender", w.Name()) globalApplication.error(message, messageArgs...) } -func (w *WebviewWindow) handleDragAndDropMessage(event *dragAndDropMessage) { +func (w *WebviewWindow) HandleDragAndDropMessage(filenames []string) { thisEvent := NewWindowEvent() ctx := newWindowEventContext() - ctx.setDroppedFiles(event.filenames) + ctx.setDroppedFiles(filenames) thisEvent.ctx = ctx for _, listener := range w.eventListeners[uint(events.FilesDropped)] { listener.callback(thisEvent) } } -func (w *WebviewWindow) openContextMenu(data *ContextMenuData) { +func (w *WebviewWindow) OpenContextMenu(data *ContextMenuData) { menu, ok := w.contextMenus[data.Id] if !ok { // try application level context menu menu, ok = globalApplication.getContextMenu(data.Id) if !ok { - w.error("No context menu found for id: %s", data.Id) + w.Error("No context menu found for id: %s", data.Id) return } } @@ -1067,7 +1101,7 @@ func (w *WebviewWindow) processKeyBinding(acceleratorString string) bool { return true } -func (w *WebviewWindow) handleKeyEvent(acceleratorString string) { +func (w *WebviewWindow) HandleKeyEvent(acceleratorString string) { if w.impl == nil { return }