5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-08 12:00:43 +08:00

[v3] Fix bindings

This commit is contained in:
Lea Anthony 2023-08-24 20:24:08 +10:00
parent 2f9f63771b
commit cdf48e0589
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
25 changed files with 1106 additions and 357 deletions

View File

@ -10,22 +10,28 @@ The electron alternative for Go
/* jshint esversion: 9 */
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("application");
let call = newRuntimeCallerWithID(objectNames.Application);
let methods = {
Hide: 0,
Show: 1,
Quit: 2,
}
/**
* Hide the application
*/
export function Hide() {
void call("Hide");
void call(methods.Hide);
}
/**
* Show the application
*/
export function Show() {
void call("Show");
void call(methods.Show);
}
@ -33,5 +39,5 @@ export function Show() {
* Quit the application
*/
export function Quit() {
void call("Quit");
void call(methods.Quit);
}

View File

@ -10,15 +10,18 @@ The electron alternative for Go
/* jshint esversion: 9 */
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("clipboard");
let call = newRuntimeCallerWithID(objectNames.Clipboard);
let ClipboardSetText = 0;
let ClipboardText = 1;
/**
* Set the Clipboard text
*/
export function SetText(text) {
void call("SetText", {text});
void call(ClipboardSetText, {text});
}
/**
@ -26,5 +29,5 @@ export function SetText(text) {
* @returns {Promise<string>}
*/
export function Text() {
return call("Text");
return call(ClipboardText);
}

View File

@ -1,9 +1,11 @@
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("contextmenu");
let call = newRuntimeCallerWithID(objectNames.ContextMenu);
let ContextMenuOpen = 0;
function openContextMenu(id, x, y, data) {
void call("OpenContextMenu", {id, x, y, data});
void call(ContextMenuOpen, {id, x, y, data});
}
export function setupContextMenus() {

View File

@ -16,11 +16,19 @@ The electron alternative for Go
* @typedef {import("./api/types").SaveDialogOptions} SaveDialogOptions
*/
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
import { nanoid } from 'nanoid/non-secure';
let call = newRuntimeCaller("dialog");
let call = newRuntimeCallerWithID(objectNames.Dialog);
let DialogInfo = 0;
let DialogWarning = 1;
let DialogError = 2;
let DialogQuestion = 3;
let DialogOpenFile = 4;
let DialogSaveFile = 5;
let dialogResponses = new Map();
@ -71,7 +79,7 @@ function dialog(type, options) {
* @returns {Promise<string>} The label of the button pressed
*/
export function Info(options) {
return dialog("Info", options);
return dialog(DialogInfo, options);
}
/**
@ -80,7 +88,7 @@ export function Info(options) {
* @returns {Promise<string>} The label of the button pressed
*/
export function Warning(options) {
return dialog("Warning", options);
return dialog(DialogWarning, options);
}
/**
@ -89,16 +97,16 @@ export function Warning(options) {
* @returns {Promise<string>} The label of the button pressed
*/
export function Error(options) {
return dialog("Error", options);
return dialog(DialogError, options);
}
/**
* Shows a Question dialog with the given options.
* @param {MessageDialogOptions} options} options
* @param {MessageDialogOptions} options
* @returns {Promise<string>} The label of the button pressed
*/
export function Question(options) {
return dialog("Question", options);
return dialog(DialogQuestion, options);
}
/**
@ -107,15 +115,15 @@ export function Question(options) {
* @returns {Promise<string[]|string>} Returns the selected file or an array of selected files if AllowsMultipleSelection is true. A blank string is returned if no file was selected.
*/
export function OpenFile(options) {
return dialog("OpenFile", options);
return dialog(DialogOpenFile, options);
}
/**
* Shows a Save dialog with the given options.
* @param {OpenDialogOptions} options
* @param {SaveDialogOptions} options
* @returns {Promise<string>} Returns the selected file. A blank string is returned if no file was selected.
*/
export function SaveFile(options) {
return dialog("SaveFile", options);
return dialog(DialogSaveFile, options);
}

View File

@ -14,9 +14,10 @@ The electron alternative for Go
* @typedef {import("./api/types").WailsEvent} WailsEvent
*/
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("events");
let call = newRuntimeCallerWithID(objectNames.Events);
let EventEmit = 0;
/**
* The Listener class defines a listener! :-)
@ -189,5 +190,5 @@ export function OffAll() {
* @param {WailsEvent} event The event to emit
*/
export function Emit(event) {
void call("Emit", event);
void call(EventEmit, event);
}

View File

@ -11,6 +11,18 @@ The electron alternative for Go
/* jshint esversion: 9 */
const runtimeURL = window.location.origin + "/wails/runtime";
// Object Names
export const objectNames = {
Call: 0,
Clipboard: 1,
Application: 2,
Events: 3,
ContextMenu: 4,
Dialog: 5,
Window: 6,
Screens: 7,
System: 8,
}
function runtimeCall(method, windowName, args) {
let url = new URL(runtimeURL);
@ -23,11 +35,11 @@ function runtimeCall(method, windowName, args) {
if (windowName) {
fetchOptions.headers["x-wails-window-name"] = windowName;
}
if (args['wails-method-id']) {
fetchOptions.headers["x-wails-method-id"] = args['wails-method-id'];
delete args['wails-method-id'];
}
if (args) {
if (args['wails-method-id']) {
fetchOptions.headers["x-wails-method-id"] = args['wails-method-id'];
delete args['wails-method-id'];
}
url.searchParams.append("args", JSON.stringify(args));
}
return new Promise((resolve, reject) => {
@ -52,4 +64,47 @@ export function newRuntimeCaller(object, windowName) {
return function (method, args=null) {
return runtimeCall(object + "." + method, windowName, args);
};
}
}
function runtimeCallWithID(objectID, method, windowName, args) {
let url = new URL(runtimeURL);
url.searchParams.append("object", objectID);
url.searchParams.append("method", method);
let fetchOptions = {
headers: {},
};
if (windowName) {
fetchOptions.headers["x-wails-window-name"] = windowName;
}
if (args) {
if (args['wails-method-id']) {
fetchOptions.headers["x-wails-method-id"] = args['wails-method-id'];
delete args['wails-method-id'];
}
url.searchParams.append("args", JSON.stringify(args));
}
return new Promise((resolve, reject) => {
fetch(url, fetchOptions)
.then(response => {
if (response.ok) {
// check content type
if (response.headers.get("Content-Type") && response.headers.get("Content-Type").indexOf("application/json") !== -1) {
return response.json();
} else {
return response.text();
}
}
reject(Error(response.statusText));
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
export function newRuntimeCallerWithID(object, windowName) {
return function (method, args=null) {
return runtimeCallWithID(object, method, windowName, args);
};
}

View File

@ -14,16 +14,20 @@ The electron alternative for Go
* @typedef {import("./api/types").Screen} Screen
*/
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("screens");
let call = newRuntimeCallerWithID(objectNames.Screens);
let ScreensGetAll = 0;
let ScreensGetPrimary = 1;
let ScreensGetCurrent = 2;
/**
* Gets all screens.
* @returns {Promise<Screen[]>}
*/
export function GetAll() {
return call("GetAll");
return call(ScreensGetAll);
}
/**
@ -31,7 +35,7 @@ export function GetAll() {
* @returns {Promise<Screen>}
*/
export function GetPrimary() {
return call("GetPrimary");
return call(ScreensGetPrimary);
}
/**
@ -40,5 +44,5 @@ export function GetPrimary() {
* @constructor
*/
export function GetCurrent() {
return call("GetCurrent");
return call(ScreensGetCurrent);
}

View File

@ -10,14 +10,16 @@ The electron alternative for Go
/* jshint esversion: 9 */
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let call = newRuntimeCaller("system");
let call = newRuntimeCallerWithID(objectNames.System);
let SystemIsDarkMode = 0;
/**
* Determines if the system is currently using dark mode
* @returns {Promise<boolean>}
*/
export function IsDarkMode() {
return call("IsDarkMode");
return call(SystemIsDarkMode);
}

View File

@ -16,139 +16,160 @@ The electron alternative for Go
* @typedef {import("../api/types").Screen} Screen
*/
import {newRuntimeCaller} from "./runtime";
import {newRuntimeCallerWithID, objectNames} from "./runtime";
let WindowCenter = 0;
let WindowSetTitle = 1;
let WindowFullscreen = 2;
let WindowUnFullscreen = 3;
let WindowSetSize = 4;
let WindowSize = 5;
let WindowSetMaxSize = 6;
let WindowSetMinSize = 7;
let WindowSetAlwaysOnTop = 8;
let WindowSetRelativePosition = 9;
let WindowRelativePosition = 10;
let WindowScreen = 11;
let WindowHide = 12;
let WindowMaximise = 13;
let WindowUnMaximise = 14;
let WindowToggleMaximise = 15;
let WindowMinimise = 16;
let WindowUnMinimise = 17;
let WindowRestore = 18;
let WindowShow = 19;
let WindowClose = 20;
let WindowSetBackgroundColour = 21;
let WindowSetResizable = 22;
let WindowWidth = 23;
let WindowHeight = 24;
let WindowZoomIn = 25;
let WindowZoomOut = 26;
let WindowZoomReset = 27;
let WindowGetZoomLevel = 28;
let WindowSetZoomLevel = 29;
export function newWindow(windowName) {
let call = newRuntimeCaller("window", windowName);
let call = newRuntimeCallerWithID(objectNames.Window, windowName);
return {
// Reload: () => call('WR'),
// ReloadApp: () => call('WR'),
// SetSystemDefaultTheme: () => call('WASDT'),
// SetLightTheme: () => call('WALT'),
// SetDarkTheme: () => call('WADT'),
// IsFullscreen: () => call('WIF'),
// IsMaximized: () => call('WIM'),
// IsMinimized: () => call('WIMN'),
// IsWindowed: () => call('WIF'),
/**
* Centers the window.
*/
Center: () => void call('Center'),
Center: () => void call(WindowCenter),
/**
* Set the window title.
* @param title
*/
SetTitle: (title) => void call('SetTitle', {title}),
SetTitle: (title) => void call(WindowSetTitle, {title}),
/**
* Makes the window fullscreen.
*/
Fullscreen: () => void call('Fullscreen'),
Fullscreen: () => void call(WindowFullscreen),
/**
* Unfullscreen the window.
*/
UnFullscreen: () => void call('UnFullscreen'),
UnFullscreen: () => void call(WindowUnFullscreen),
/**
* Set the window size.
* @param {number} width The window width
* @param {number} height The window height
*/
SetSize: (width, height) => call('SetSize', {width,height}),
SetSize: (width, height) => call(WindowSetSize, {width,height}),
/**
* Get the window size.
* @returns {Promise<Size>} The window size
*/
Size: () => { return call('Size'); },
Size: () => { return call(WindowSize); },
/**
* Set the window maximum size.
* @param {number} width
* @param {number} height
*/
SetMaxSize: (width, height) => void call('SetMaxSize', {width,height}),
SetMaxSize: (width, height) => void call(WindowSetMaxSize, {width,height}),
/**
* Set the window minimum size.
* @param {number} width
* @param {number} height
*/
SetMinSize: (width, height) => void call('SetMinSize', {width,height}),
SetMinSize: (width, height) => void call(WindowSetMinSize, {width,height}),
/**
* Set window to be always on top.
* @param {boolean} onTop Whether the window should be always on top
*/
SetAlwaysOnTop: (onTop) => void call('SetAlwaysOnTop', {alwaysOnTop:onTop}),
SetAlwaysOnTop: (onTop) => void call(WindowSetAlwaysOnTop, {alwaysOnTop:onTop}),
/**
* Set the window relative position.
* @param {number} x
* @param {number} y
*/
SetRelativePosition: (x, y) => call('SetRelativePosition', {x,y}),
SetRelativePosition: (x, y) => call(WindowSetRelativePosition, {x,y}),
/**
* Get the window position.
* @returns {Promise<Position>} The window position
*/
RelativePosition: () => { return call('RelativePosition'); },
RelativePosition: () => { return call(WindowRelativePosition); },
/**
* Get the screen the window is on.
* @returns {Promise<Screen>}
*/
Screen: () => { return call('Screen'); },
Screen: () => { return call(WindowScreen); },
/**
* Hide the window
*/
Hide: () => void call('Hide'),
Hide: () => void call(WindowHide),
/**
* Maximise the window
*/
Maximise: () => void call('Maximise'),
Maximise: () => void call(WindowMaximise),
/**
* Show the window
*/
Show: () => void call('Show'),
Show: () => void call(WindowShow),
/**
* Close the window
*/
Close: () => void call('Close'),
Close: () => void call(WindowClose),
/**
* Toggle the window maximise state
*/
ToggleMaximise: () => void call('ToggleMaximise'),
ToggleMaximise: () => void call(WindowToggleMaximise),
/**
* Unmaximise the window
*/
UnMaximise: () => void call('UnMaximise'),
UnMaximise: () => void call(WindowUnMaximise),
/**
* Minimise the window
*/
Minimise: () => void call('Minimise'),
Minimise: () => void call(WindowMinimise),
/**
* Unminimise the window
*/
UnMinimise: () => void call('UnMinimise'),
UnMinimise: () => void call(WindowUnMinimise),
/**
* Restore the window
*/
Restore: () => void call('Restore'),
Restore: () => void call(WindowRestore),
/**
* Set the background colour of the window.
@ -157,6 +178,51 @@ export function newWindow(windowName) {
* @param {number} b - A value between 0 and 255
* @param {number} a - A value between 0 and 255
*/
SetBackgroundColour: (r, g, b, a) => void call('SetBackgroundColour', {r, g, b, a}),
SetBackgroundColour: (r, g, b, a) => void call(WindowSetBackgroundColour, {r, g, b, a}),
/**
* Set whether the window can be resized or not
* @param {boolean} resizable
*/
SetResizable: (resizable) => void call(WindowSetResizable, {resizable}),
/**
* Get the window width
* @returns {Promise<number>}
*/
Width: () => { return call(WindowWidth); },
/**
* Get the window height
* @returns {Promise<number>}
*/
Height: () => { return call(WindowHeight); },
/**
* Zoom in the window
*/
ZoomIn: () => void call(WindowZoomIn),
/**
* Zoom out the window
*/
ZoomOut: () => void call(WindowZoomOut),
/**
* Reset the window zoom
*/
ZoomReset: () => void call(WindowZoomReset),
/**
* Get the window zoom
* @returns {Promise<number>}
*/
GetZoomLevel: () => { return call(WindowGetZoomLevel); },
/**
* Set the window zoom level
* @param {number} zoomLevel
*/
SetZoomLevel: (zoomLevel) => void call(WindowSetZoomLevel, {zoomLevel}),
};
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,18 @@ import (
// TODO maybe we could use a new struct that has the targetWindow as an attribute so we could get rid of passing the targetWindow
// as parameter through every function call.
const (
callRequest int = 0
clipboardRequest = 1
applicationRequest = 2
eventsRequest = 3
contextMenuRequest = 4
dialogRequest = 5
windowRequest = 6
screensRequest = 7
systemRequest = 8
)
type MessageProcessor struct {
pluginManager *PluginManager
logger *slog.Logger
@ -53,6 +65,11 @@ func (m *MessageProcessor) getTargetWindow(r *http.Request) *WebviewWindow {
}
func (m *MessageProcessor) HandleRuntimeCall(rw http.ResponseWriter, r *http.Request) {
object := r.URL.Query().Get("object")
if object != "" {
m.HandleRuntimeCallWithIDs(rw, r)
return
}
// Read "method" from query string
method := r.URL.Query().Get("method")
if method == "" {
@ -65,7 +82,7 @@ func (m *MessageProcessor) HandleRuntimeCall(rw http.ResponseWriter, r *http.Req
return
}
// Get the object
object := splitMethod[0]
object = splitMethod[0]
// Get the method
method = splitMethod[1]
@ -78,23 +95,66 @@ func (m *MessageProcessor) HandleRuntimeCall(rw http.ResponseWriter, r *http.Req
}
switch object {
case "window":
m.processWindowMethod(method, rw, r, targetWindow, params)
case "clipboard":
m.processClipboardMethod(method, rw, r, targetWindow, params)
case "dialog":
m.processDialogMethod(method, rw, r, targetWindow, params)
case "events":
m.processEventsMethod(method, rw, r, targetWindow, params)
case "application":
m.processApplicationMethod(method, rw, r, targetWindow, params)
case "contextmenu":
m.processContextMenuMethod(method, rw, r, targetWindow, params)
case "screens":
m.processScreensMethod(method, rw, r, targetWindow, params)
//case "window":
// m.processWindowMethod(method, rw, r, targetWindow, params)
//case "clipboard":
// m.processClipboardMethod(method, rw, r, targetWindow, params)
//case "dialog":
// m.processDialogMethod(method, rw, r, targetWindow, params)
//case "events":
// m.processEventsMethod(method, rw, r, targetWindow, params)
//case "application":
// m.processApplicationMethod(method, rw, r, targetWindow, params)
//case "contextmenu":
// m.processContextMenuMethod(method, rw, r, targetWindow, params)
//case "screens":
// m.processScreensMethod(method, rw, r, targetWindow, params)
case "call":
m.processCallMethod(method, rw, r, targetWindow, params)
case "system":
//case "system":
// m.processSystemMethod(method, rw, r, targetWindow, params)
default:
m.httpError(rw, "Unknown runtime call: %s", object)
}
}
func (m *MessageProcessor) HandleRuntimeCallWithIDs(rw http.ResponseWriter, r *http.Request) {
object, err := strconv.Atoi(r.URL.Query().Get("object"))
if err != nil {
m.httpError(rw, "Error decoding object value: "+err.Error())
return
}
method, err := strconv.Atoi(r.URL.Query().Get("method"))
if err != nil {
m.httpError(rw, "Error decoding method value: "+err.Error())
return
}
params := QueryParams(r.URL.Query())
targetWindow := m.getTargetWindow(r)
if targetWindow == nil {
m.httpError(rw, "No valid window found")
return
}
switch object {
case windowRequest:
m.processWindowMethod(method, rw, r, targetWindow, params)
case clipboardRequest:
m.processClipboardMethod(method, rw, r, targetWindow, params)
case dialogRequest:
m.processDialogMethod(method, rw, r, targetWindow, params)
case eventsRequest:
m.processEventsMethod(method, rw, r, targetWindow, params)
case applicationRequest:
m.processApplicationMethod(method, rw, r, targetWindow, params)
case contextMenuRequest:
m.processContextMenuMethod(method, rw, r, targetWindow, params)
case screensRequest:
m.processScreensMethod(method, rw, r, targetWindow, params)
//case callRequest:
// m.processCallMethod(method, rw, r, targetWindow, params)
case systemRequest:
m.processSystemMethod(method, rw, r, targetWindow, params)
default:
m.httpError(rw, "Unknown runtime call: %s", object)

View File

@ -4,24 +4,34 @@ import (
"net/http"
)
func (m *MessageProcessor) processApplicationMethod(method string, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
const (
ApplicationQuit = 0
ApplicationHide = 1
ApplicationShow = 2
)
var applicationMethodNames = map[int]string{
ApplicationQuit: "Quit",
ApplicationHide: "Hide",
ApplicationShow: "Show",
}
func (m *MessageProcessor) processApplicationMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
switch method {
case "Quit":
case ApplicationQuit:
globalApplication.Quit()
m.ok(rw)
case "Hide":
case ApplicationHide:
globalApplication.Hide()
m.ok(rw)
case "Show":
case ApplicationShow:
globalApplication.Show()
m.ok(rw)
case "IsDarkMode":
m.json(rw, globalApplication.IsDarkMode())
default:
m.httpError(rw, "Unknown application method: %s", method)
m.httpError(rw, "Unknown application method: %d", method)
}
m.Info("Runtime:", "method", "Application."+method)
m.Info("Runtime Call:", "method", "Application."+applicationMethodNames[method])
}

View File

@ -39,18 +39,23 @@ func (m *MessageProcessor) processCallMethod(method string, rw http.ResponseWrit
return
}
var boundMethod *BoundMethod
id, err := strconv.ParseUint(r.Header.Get("x-wails-method-id"), 10, 32)
if err != nil {
m.callErrorCallback(window, "Error parsing method id for call: %s", callID, err)
return
}
if id != 0 {
boundMethod = globalApplication.bindings.GetByID(uint32(id))
} else {
methodID := r.Header.Get("x-wails-method-id")
if methodID == "" {
boundMethod = globalApplication.bindings.Get(&options)
if boundMethod == nil {
m.callErrorCallback(window, "Error getting binding for method: %s", callID, fmt.Errorf("method '%s' not found", options.Name()))
return
}
} else {
id, err := strconv.ParseUint(methodID, 10, 32)
if err != nil {
m.callErrorCallback(window, "Error parsing method id for call: %s", callID, err)
return
}
boundMethod = globalApplication.bindings.GetByID(uint32(id))
}
if boundMethod == nil {
m.callErrorCallback(window, "Error getting binding for method: %s", callID, fmt.Errorf("'%s' not found", options.MethodName))
m.callErrorCallback(window, "Error getting binding for method: %s", callID, fmt.Errorf("method ID '%s' not found", options.Name()))
return
}
go func() {

View File

@ -4,24 +4,41 @@ import (
"net/http"
)
func (m *MessageProcessor) processClipboardMethod(method string, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, params QueryParams) {
const (
ClipboardSetText = 0
ClipboardText = 1
)
var clipboardMethods = map[int]string{
ClipboardSetText: "SetText",
ClipboardText: "Text",
}
func (m *MessageProcessor) processClipboardMethod(method int, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, params QueryParams) {
args, err := params.Args()
if err != nil {
m.httpError(rw, "Unable to parse arguments: %s", err)
return
}
switch method {
case "SetText":
text := params.String("text")
case ClipboardSetText:
text := args.String("text")
if text == nil {
m.Error("SetText: text is required")
return
}
globalApplication.Clipboard().SetText(*text)
m.ok(rw)
m.Info("", "method", "Clipboard."+method, "text", *text)
case "Text":
m.Info("Runtime Call:", "method", "Clipboard."+clipboardMethods[method], "text", *text)
case ClipboardText:
text, _ := globalApplication.Clipboard().Text()
m.text(rw, text)
m.Info("", "method", "Clipboard."+method, "text", text)
m.Info("Runtime Call:", "method", "Clipboard."+clipboardMethods[method], "text", text)
default:
m.httpError(rw, "Unknown clipboard method: %s", method)
return
}
}

View File

@ -11,10 +11,18 @@ type ContextMenuData struct {
Data any `json:"data"`
}
func (m *MessageProcessor) processContextMenuMethod(method string, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
const (
ContextMenuOpen = 0
)
var contextmenuMethodNames = map[int]string{
ContextMenuOpen: "Open",
}
func (m *MessageProcessor) processContextMenuMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
switch method {
case "OpenContextMenu":
case ContextMenuOpen:
var data ContextMenuData
err := params.ToStruct(&data)
if err != nil {
@ -27,6 +35,6 @@ func (m *MessageProcessor) processContextMenuMethod(method string, rw http.Respo
m.httpError(rw, "Unknown contextmenu method: %s", method)
}
m.Info("Runtime:", "method", "ContextMenu."+method)
m.Info("Runtime:", "method", "ContextMenu."+contextmenuMethodNames[method])
}

View File

@ -8,6 +8,24 @@ import (
"strconv"
)
const (
DialogInfo = 0
DialogWarning = 1
DialogError = 2
DialogQuestion = 3
DialogOpenFile = 4
DialogSaveFile = 5
)
var dialogMethodNames = map[int]string{
DialogInfo: "Info",
DialogWarning: "Warning",
DialogError: "Error",
DialogQuestion: "Question",
DialogOpenFile: "OpenFile",
DialogSaveFile: "SaveFile",
}
func (m *MessageProcessor) dialogErrorCallback(window *WebviewWindow, message string, dialogID *string, err error) {
errorMsg := fmt.Sprintf(message, err)
m.Error(errorMsg)
@ -21,7 +39,7 @@ func (m *MessageProcessor) dialogCallback(window *WebviewWindow, dialogID *strin
window.ExecJS(msg)
}
func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
func (m *MessageProcessor) processDialogMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
args, err := params.Args()
if err != nil {
@ -33,8 +51,11 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
m.Error("dialog-id is required")
return
}
var methodName = "Dialog." + dialogMethodNames[method]
switch method {
case "Info", "Warning", "Error", "Question":
case DialogInfo, DialogWarning, DialogError, DialogQuestion:
var options MessageDialogOptions
err := params.ToStruct(&options)
if err != nil {
@ -49,13 +70,13 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
}
var dialog *MessageDialog
switch method {
case "Info":
case DialogInfo:
dialog = InfoDialog()
case "Warning":
case DialogWarning:
dialog = WarningDialog()
case "Error":
case DialogError:
dialog = ErrorDialog()
case "Question":
case DialogQuestion:
dialog = QuestionDialog()
}
var detached = args.Bool("Detached")
@ -74,9 +95,9 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
dialog.AddButtons(options.Buttons)
dialog.Show()
m.ok(rw)
m.Info("Runtime:", "method", "Dialog."+method, "options", options)
m.Info("Runtime:", "method", methodName, "options", options)
case "OpenFile":
case DialogOpenFile:
var options OpenFileDialogOptions
err := params.ToStruct(&options)
if err != nil {
@ -102,7 +123,7 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
return
}
m.dialogCallback(window, dialogID, string(result), true)
m.Info("Runtime:", "method", "Dialog."+method, "result", result)
m.Info("Runtime:", "method", methodName, "result", result)
}
} else {
file, err := dialog.PromptForSingleSelection()
@ -111,13 +132,13 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
return
}
m.dialogCallback(window, dialogID, file, false)
m.Info("Runtime:", "method", "Dialog."+method, "result", file)
m.Info("Runtime:", "method", methodName, "result", file)
}
}()
m.ok(rw)
m.Info("Runtime:", "method", "Dialog."+method, "options", options)
m.Info("Runtime:", "method", methodName, "options", options)
case "SaveFile":
case DialogSaveFile:
var options SaveFileDialogOptions
err := params.ToStruct(&options)
if err != nil {
@ -137,10 +158,10 @@ func (m *MessageProcessor) processDialogMethod(method string, rw http.ResponseWr
return
}
m.dialogCallback(window, dialogID, file, false)
m.Info("Runtime:", "method", "Dialog."+method, "result", file)
m.Info("Runtime:", "method", methodName, "result", file)
}()
m.ok(rw)
m.Info("Runtime:", "method", "Dialog."+method, "options", options)
m.Info("Runtime:", "method", methodName, "options", options)
default:
m.httpError(rw, "Unknown dialog method: %s", method)

View File

@ -4,12 +4,20 @@ import (
"net/http"
)
func (m *MessageProcessor) processEventsMethod(method string, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
const (
EventsEmit = 0
)
var eventsMethodNames = map[int]string{
EventsEmit: "Emit",
}
func (m *MessageProcessor) processEventsMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
var event WailsEvent
switch method {
case "Emit":
case EventsEmit:
err := params.ToStruct(&event)
if err != nil {
m.httpError(rw, "Error parsing event: %s", err)
@ -27,6 +35,6 @@ func (m *MessageProcessor) processEventsMethod(method string, rw http.ResponseWr
return
}
m.Info("Runtime:", "method", "Events."+method, "event", event)
m.Info("Runtime:", "method", "Events."+eventsMethodNames[method], "event", event)
}

View File

@ -4,24 +4,36 @@ import (
"net/http"
)
func (m *MessageProcessor) processScreensMethod(method string, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, _ QueryParams) {
const (
ScreensGetAll = 0
ScreensGetPrimary = 1
ScreensGetCurrent = 2
)
var screensMethodNames = map[int]string{
ScreensGetAll: "GetAll",
ScreensGetPrimary: "GetPrimary",
ScreensGetCurrent: "GetCurrent",
}
func (m *MessageProcessor) processScreensMethod(method int, rw http.ResponseWriter, _ *http.Request, _ *WebviewWindow, _ QueryParams) {
switch method {
case "GetAll":
case ScreensGetAll:
screens, err := globalApplication.GetScreens()
if err != nil {
m.Error("GetAll: %s", err.Error())
return
}
m.json(rw, screens)
case "GetPrimary":
case ScreensGetPrimary:
screen, err := globalApplication.GetPrimaryScreen()
if err != nil {
m.Error("GetPrimary: %s", err.Error())
return
}
m.json(rw, screen)
case "GetCurrent":
case ScreensGetCurrent:
screen, err := globalApplication.CurrentWindow().GetScreen()
if err != nil {
m.Error("GetCurrent: %s", err.Error())
@ -32,6 +44,6 @@ func (m *MessageProcessor) processScreensMethod(method string, rw http.ResponseW
m.httpError(rw, "Unknown screens method: %s", method)
}
m.Info("Runtime:", "method", "Screens."+method)
m.Info("Runtime:", "method", "Screens."+screensMethodNames[method])
}

View File

@ -4,15 +4,23 @@ import (
"net/http"
)
func (m *MessageProcessor) processSystemMethod(method string, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
const (
SystemIsDarkMode = 0
)
var systemMethodNames = map[int]string{
SystemIsDarkMode: "IsDarkMode",
}
func (m *MessageProcessor) processSystemMethod(method int, rw http.ResponseWriter, r *http.Request, window *WebviewWindow, params QueryParams) {
switch method {
case "IsDarkMode":
case SystemIsDarkMode:
m.json(rw, globalApplication.IsDarkMode())
default:
m.httpError(rw, "Unknown system method: %s", method)
}
m.Info("Runtime:", "method", "System."+method)
m.Info("Runtime:", "method", "System."+systemMethodNames[method])
}

View File

@ -4,7 +4,73 @@ import (
"net/http"
)
func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
const (
WindowCenter = 0
WindowSetTitle = 1
WindowFullscreen = 2
WindowUnFullscreen = 3
WindowSetSize = 4
WindowSize = 5
WindowSetMaxSize = 6
WindowSetMinSize = 7
WindowSetAlwaysOnTop = 8
WindowSetRelativePosition = 9
WindowRelativePosition = 10
WindowScreen = 11
WindowHide = 12
WindowMaximise = 13
WindowUnMaximise = 14
WindowToggleMaximise = 15
WindowMinimise = 16
WindowUnMinimise = 17
WindowRestore = 18
WindowShow = 19
WindowClose = 20
WindowSetBackgroundColour = 21
WindowSetResizable = 22
WindowWidth = 23
WindowHeight = 24
WindowZoomIn = 25
WindowZoomOut = 26
WindowZoomReset = 27
WindowGetZoomLevel = 28
WindowSetZoomLevel = 29
)
var windowMethods = map[int]string{
WindowCenter: "Center",
WindowSetTitle: "SetTitle",
WindowFullscreen: "Fullscreen",
WindowUnFullscreen: "UnFullscreen",
WindowSetSize: "SetSize",
WindowSize: "Size",
WindowSetMaxSize: "SetMaxSize",
WindowSetMinSize: "SetMinSize",
WindowSetAlwaysOnTop: "SetAlwaysOnTop",
WindowSetRelativePosition: "SetRelativePosition",
WindowRelativePosition: "RelativePosition",
WindowScreen: "Screen",
WindowHide: "Hide",
WindowMaximise: "Maximise",
WindowUnMaximise: "UnMaximise",
WindowToggleMaximise: "ToggleMaximise",
WindowMinimise: "Minimise",
WindowUnMinimise: "UnMinimise",
WindowRestore: "Restore",
WindowShow: "Show",
WindowClose: "Close",
WindowSetBackgroundColour: "SetBackgroundColour",
WindowSetResizable: "SetResizable",
WindowWidth: "Width",
WindowHeight: "Height",
WindowZoomIn: "ZoomIn",
WindowZoomOut: "ZoomOut",
WindowZoomReset: "ZoomReset",
WindowGetZoomLevel: "GetZoomLevel",
WindowSetZoomLevel: "SetZoomLevel",
}
func (m *MessageProcessor) processWindowMethod(method int, rw http.ResponseWriter, _ *http.Request, window *WebviewWindow, params QueryParams) {
args, err := params.Args()
if err != nil {
@ -13,7 +79,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
switch method {
case "SetTitle":
case WindowSetTitle:
title := args.String("title")
if title == nil {
m.Error("SetTitle: title is required")
@ -21,7 +87,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetTitle(*title)
m.ok(rw)
case "SetSize":
case WindowSetSize:
width := args.Int("width")
height := args.Int("height")
if width == nil || height == nil {
@ -30,7 +96,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetSize(*width, *height)
m.ok(rw)
case "SetRelativePosition":
case WindowSetRelativePosition:
x := args.Int("x")
y := args.Int("y")
if x == nil || y == nil {
@ -39,52 +105,52 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetRelativePosition(*x, *y)
m.ok(rw)
case "Fullscreen":
case WindowFullscreen:
window.Fullscreen()
m.ok(rw)
case "UnFullscreen":
case WindowUnFullscreen:
window.UnFullscreen()
m.ok(rw)
case "Minimise":
case WindowMinimise:
window.Minimise()
m.ok(rw)
case "UnMinimise":
case WindowUnMinimise:
window.UnMinimise()
m.ok(rw)
case "Maximise":
case WindowMaximise:
window.Maximise()
m.ok(rw)
case "UnMaximise":
case WindowUnMaximise:
window.UnMaximise()
m.ok(rw)
case "Restore":
case WindowRestore:
window.Restore()
m.ok(rw)
case "Show":
case WindowShow:
window.Show()
m.ok(rw)
case "Hide":
case WindowHide:
window.Hide()
m.ok(rw)
case "Close":
case WindowClose:
window.Close()
m.ok(rw)
case "Center":
case WindowCenter:
window.Center()
m.ok(rw)
case "Size":
case WindowSize:
width, height := window.Size()
m.json(rw, map[string]interface{}{
"width": width,
"height": height,
})
case "RelativePosition":
case WindowRelativePosition:
x, y := window.RelativePosition()
m.json(rw, map[string]interface{}{
"x": x,
"y": y,
})
case "SetBackgroundColour":
case WindowSetBackgroundColour:
r := args.UInt8("r")
if r == nil {
m.Error("Invalid SetBackgroundColour Message: 'r' value required")
@ -112,7 +178,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
Alpha: *a,
})
m.ok(rw)
case "SetAlwaysOnTop":
case WindowSetAlwaysOnTop:
alwaysOnTop := args.Bool("alwaysOnTop")
if alwaysOnTop == nil {
m.Error("Invalid SetAlwaysOnTop Message: 'alwaysOnTop' value required")
@ -120,7 +186,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetAlwaysOnTop(*alwaysOnTop)
m.ok(rw)
case "SetResizable":
case WindowSetResizable:
resizable := args.Bool("resizable")
if resizable == nil {
m.Error("Invalid SetResizable Message: 'resizable' value required")
@ -128,7 +194,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetResizable(*resizable)
m.ok(rw)
case "SetMinSize":
case WindowSetMinSize:
width := args.Int("width")
height := args.Int("height")
if width == nil || height == nil {
@ -137,7 +203,7 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetMinSize(*width, *height)
m.ok(rw)
case "SetMaxSize":
case WindowSetMaxSize:
width := args.Int("width")
height := args.Int("height")
if width == nil || height == nil {
@ -146,38 +212,38 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
}
window.SetMaxSize(*width, *height)
m.ok(rw)
case "Width":
case WindowWidth:
width := window.Width()
m.json(rw, map[string]interface{}{
"width": width,
})
case "Height":
case WindowHeight:
height := window.Height()
m.json(rw, map[string]interface{}{
"height": height,
})
case "ZoomIn":
case WindowZoomIn:
window.ZoomIn()
m.ok(rw)
case "ZoomOut":
case WindowZoomOut:
window.ZoomOut()
m.ok(rw)
case "ZoomReset":
case WindowZoomReset:
window.ZoomReset()
m.ok(rw)
case "GetZoom":
case WindowGetZoomLevel:
zoomLevel := window.GetZoom()
m.json(rw, map[string]interface{}{
"zoomLevel": zoomLevel,
})
case "Screen":
case WindowScreen:
screen, err := window.GetScreen()
if err != nil {
m.httpError(rw, err.Error())
return
}
m.json(rw, screen)
case "SetZoom":
case WindowSetZoomLevel:
zoomLevel := args.Float64("zoomLevel")
if zoomLevel == nil {
m.Error("Invalid SetZoom Message: invalid 'zoomLevel' value")
@ -186,10 +252,10 @@ func (m *MessageProcessor) processWindowMethod(method string, rw http.ResponseWr
window.SetZoom(*zoomLevel)
m.ok(rw)
default:
m.httpError(rw, "Unknown window method: %s", method)
m.httpError(rw, "Unknown window method id: %s", method)
}
var logArgs = []any{"method", "Window." + method}
var logArgs = []any{"method", method}
for name, arg := range args.data {
logArgs = append(logArgs, name)
logArgs = append(logArgs, arg)