[v2] Support Window runtime in JS

This commit is contained in:
Lea Anthony
2021-09-09 20:10:18 +10:00
parent 414b0149f2
commit cae9827841
13 changed files with 618 additions and 28 deletions
+25 -14
View File
@@ -3,6 +3,8 @@ package dispatcher
import (
"encoding/json"
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend"
"strings"
)
type callMessage struct {
@@ -11,29 +13,38 @@ type callMessage struct {
CallbackID string `json:"callbackID"`
}
func (d *Dispatcher) processCallMessage(message string) (string, error) {
func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend) (string, error) {
var payload callMessage
err := json.Unmarshal([]byte(message[1:]), &payload)
if err != nil {
return "", err
}
// Lookup method
registeredMethod := d.bindingsDB.GetMethod(payload.Name)
// Check we have it
if registeredMethod == nil {
return "", fmt.Errorf("method '%s' not registered", payload.Name)
var result interface{}
// Handle different calls
switch true {
case strings.HasPrefix(payload.Name, systemCallPrefix):
result, err = d.processSystemCall(payload, sender)
default:
// Lookup method
registeredMethod := d.bindingsDB.GetMethod(payload.Name)
// Check we have it
if registeredMethod == nil {
return "", fmt.Errorf("method '%s' not registered", payload.Name)
}
args, err2 := registeredMethod.ParseArgs(payload.Args)
if err2 != nil {
errmsg := fmt.Errorf("error parsing arguments: %s", err2.Error())
result, _ := d.NewErrorCallback(errmsg.Error(), payload.CallbackID)
return result, errmsg
}
result, err = registeredMethod.Call(args)
}
args, err := registeredMethod.ParseArgs(payload.Args)
if err != nil {
errmsg := fmt.Errorf("error parsing arguments: %s", err.Error())
result, _ := d.NewErrorCallback(errmsg.Error(), payload.CallbackID)
return result, errmsg
}
result, err := registeredMethod.Call(args)
callbackMessage := &CallbackMessage{
CallbackID: payload.CallbackID,
}
@@ -33,7 +33,9 @@ func (d *Dispatcher) ProcessMessage(message string, sender frontend.Frontend) (s
case 'E':
return d.processEventMessage(message, sender)
case 'C':
return d.processCallMessage(message)
return d.processCallMessage(message, sender)
case 'W':
return d.processWindowMessage(message, sender)
default:
return "", errors.New("Unknown message from front end: " + message)
}
@@ -0,0 +1,37 @@
package dispatcher
import (
"fmt"
"github.com/wailsapp/wails/v2/internal/frontend"
"strings"
)
const systemCallPrefix = ":wails:"
type position struct {
X int `json:"x"`
Y int `json:"y"`
}
type size struct {
W int `json:"w"`
H int `json:"h"`
}
func (d *Dispatcher) processSystemCall(payload callMessage, sender frontend.Frontend) (interface{}, error) {
// Strip prefix
name := strings.TrimPrefix(payload.Name, systemCallPrefix)
switch name {
case "WindowGetPos":
x, y := sender.WindowGetPos()
return &position{x, y}, nil
case "WindowGetSize":
w, h := sender.WindowGetSize()
return &position{w, h}, nil
default:
return nil, fmt.Errorf("unknown systemcall message: %s", payload.Name)
}
}
+72
View File
@@ -0,0 +1,72 @@
package dispatcher
import (
"errors"
"github.com/wailsapp/wails/v2/internal/frontend"
"strconv"
"strings"
)
func (d *Dispatcher) mustAtoI(input string) int {
result, err := strconv.Atoi(input)
if err != nil {
d.log.Error("cannot convert %s to integer!", input)
}
return result
}
func (d *Dispatcher) processWindowMessage(message string, sender frontend.Frontend) (string, error) {
if len(message) < 2 {
return "", errors.New("Invalid Event Message: " + message)
}
switch message[1] {
case 'c':
go sender.WindowCenter()
case 'T':
title := message[2:]
go sender.WindowSetTitle(title)
case 'F':
go sender.WindowFullscreen()
case 'f':
go sender.WindowUnFullscreen()
case 's':
parts := strings.Split(message[3:], ":")
w := d.mustAtoI(parts[0])
h := d.mustAtoI(parts[1])
go sender.WindowSetSize(w, h)
case 'p':
parts := strings.Split(message[3:], ":")
x := d.mustAtoI(parts[0])
y := d.mustAtoI(parts[1])
go sender.WindowSetPos(x, y)
case 'H':
go sender.WindowHide()
case 'S':
go sender.WindowShow()
case 'M':
go sender.WindowMaximise()
case 'U':
go sender.WindowUnmaximise()
case 'm':
go sender.WindowMinimise()
case 'u':
go sender.WindowUnminimise()
case 'Z':
parts := strings.Split(message[3:], ":")
w := d.mustAtoI(parts[0])
h := d.mustAtoI(parts[1])
go sender.WindowSetMaxSize(w, h)
case 'z':
parts := strings.Split(message[3:], ":")
w := d.mustAtoI(parts[0])
h := d.mustAtoI(parts[1])
go sender.WindowSetMinSize(w, h)
case 'C':
sender.Quit()
default:
d.log.Error("unknown Window message: %s", message)
}
return "", nil
}
@@ -11,6 +11,7 @@ The electron alternative for Go
import {Call} from './calls';
// This is where we bind go method wrappers
window.go = {};
export function SetBindings(bindingsMap) {
@@ -50,7 +50,7 @@ if (window.crypto) {
*
* @export
* @param {string} name
* @param {string} args
* @param {any=} args
* @param {number=} timeout
* @returns
*/
+5 -6
View File
@@ -12,22 +12,20 @@ import * as Log from './log';
import {eventListeners, EventsEmit, EventsNotify, EventsOff, EventsOn, EventsOnce, EventsOnMultiple} from './events';
import {Callback, callbacks} from './calls';
import {SetBindings} from "./bindings";
import {WindowReload} from "./window";
// Backend is where the Go struct wrappers get bound to
window.backend = {};
import * as Window from "./window";
// The JS runtime
window.runtime = {
...Log,
...Window,
EventsOn,
EventsOnce,
EventsOnMultiple,
EventsEmit,
EventsOff,
WindowReload,
};
// Initialise global if not already
// Internal wails endpoints
window.wails = {
Callback,
EventsNotify,
@@ -36,6 +34,7 @@ window.wails = {
callbacks
};
// Set the bindings
window.wails.SetBindings(window.wailsbindings);
delete window.wails.SetBindings;
@@ -10,6 +10,174 @@ The electron alternative for Go
/* jshint esversion: 9 */
import {Call} from "./calls";
export function WindowReload() {
window.location.reload();
}
/**
* Place the window in the center of the screen
*
* @export
*/
export function WindowCenter() {
window.WailsInvoke('Wc');
}
/**
* Sets the window title
*
* @param {string} title
* @export
*/
export function WindowSetTitle(title) {
window.WailsInvoke('WT' + title);
}
/**
* Makes the window go fullscreen
*
* @export
*/
export function WindowFullscreen() {
window.WailsInvoke('WF');
}
/**
* Reverts the window from fullscreen
*
* @export
*/
export function WindowUnFullscreen() {
window.WailsInvoke('Wf');
}
/**
* Set the Size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetSize(width, height) {
window.WailsInvoke('Ws:' + width + ':' + height);
}
/**
* Get the Size of the window
*
* @export
* @return {Promise<{w: number, h: number}>} The size of the window
*/
export function WindowGetSize() {
return Call(":wails:WindowGetSize");
}
/**
* Set the maximum size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetMaxSize(width, height) {
window.WailsInvoke('WZ:' + width + ':' + height);
}
/**
* Set the minimum size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetMinSize(width, height) {
window.WailsInvoke('Wz:' + width + ':' + height);
}
/**
* Set the Position of the window
*
* @export
* @param {number} x
* @param {number} y
*/
export function WindowSetPosition(x, y) {
window.WailsInvoke('Wp:' + x + ':' + y);
}
/**
* Get the Position of the window
*
* @export
* @return {Promise<{x: number, y: number}>} The position of the window
*/
export function WindowGetPosition() {
return Call(":wails:WindowGetPos");
}
/**
* Hide the Window
*
* @export
*/
export function WindowHide() {
window.WailsInvoke('WH');
}
/**
* Show the Window
*
* @export
*/
export function WindowShow() {
window.WailsInvoke('WS');
}
/**
* Maximise the Window
*
* @export
*/
export function WindowMaximise() {
window.WailsInvoke('WM');
}
/**
* Unmaximise the Window
*
* @export
*/
export function WindowUnmaximise() {
window.WailsInvoke('WU');
}
/**
* Minimise the Window
*
* @export
*/
export function WindowMinimise() {
window.WailsInvoke('Wm');
}
/**
* Unminimise the Window
*
* @export
*/
export function WindowUnminimise() {
window.WailsInvoke('Wu');
}
/**
* Close the Window
*
* @export
*/
export function WindowClose() {
window.WailsInvoke('WC');
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+45
View File
@@ -1,3 +1,14 @@
interface Position {
x: number;
y: number;
}
interface Size {
w: number;
h: number;
}
interface runtime {
EventsEmit(eventName: string, data?: any): void;
@@ -20,6 +31,40 @@ interface runtime {
LogWarning(message: string): void;
WindowReload(): void;
WindowCenter(): void
WindowSetTitle(title: string): void
WindowFullscreen(): void
WindowUnFullscreen(): void
WindowSetSize(width: number, height: number): Promise<Size>
WindowGetSize(): Promise<Size>
WindowSetMaxSize(width: number, height: number): void
WindowSetMinSize(width: number, height: number): void
WindowSetPosition(x: number, y: number): void
WindowGetPosition(): Promise<Position>
WindowHide(): void
WindowShow(): void
WindowMaximise(): void
WindowUnmaximise(): void
WindowMinimise(): void
WindowUnminimise(): void
WindowClose(): void
}
declare global {
File diff suppressed because one or more lines are too long
@@ -18,3 +18,169 @@ The electron alternative for Go
export function WindowReload() {
window.runtime.WindowReload();
}
/**
* Place the window in the center of the screen
*
* @export
*/
export function WindowCenter() {
window.runtime.WindowCenter();
}
/**
* Sets the window title
*
* @param {string} title
* @export
*/
export function WindowSetTitle(title) {
window.runtime.WindowSetTitle(title);
}
/**
* Makes the window go fullscreen
*
* @export
*/
export function WindowFullscreen() {
window.runtime.WindowFullscreen();
}
/**
* Reverts the window from fullscreen
*
* @export
*/
export function WindowUnFullscreen() {
window.runtime.WindowUnFullscreen();
}
/**
* Get the Size of the window
*
* @export
* @return {Promise<{w: number, h: number}>} The size of the window
*/
export function WindowGetSize() {
window.runtime.WindowGetSize();
}
/**
* Set the Size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetSize(width, height) {
window.runtime.WindowSetSize(width, height);
}
/**
* Set the maximum size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetMaxSize(width, height) {
window.runtime.WindowSetMaxSize(width, height);
}
/**
* Set the minimum size of the window
*
* @export
* @param {number} width
* @param {number} height
*/
export function WindowSetMinSize(width, height) {
window.runtime.WindowSetMinSize(width, height);
}
/**
* Set the Position of the window
*
* @export
* @param {number} x
* @param {number} y
*/
export function WindowSetPosition(x, y) {
window.runtime.WindowSetPosition(x, y);
}
/**
* Get the Position of the window
*
* @export
* @return {Promise<{x: number, y: number}>} The position of the window
*/
export function WindowGetPosition() {
window.runtime.WindowGetPosition();
}
/**
* Hide the Window
*
* @export
*/
export function WindowHide() {
window.runtime.WindowHide();
}
/**
* Show the Window
*
* @export
*/
export function WindowShow() {
window.runtime.WindowShow();
}
/**
* Maximise the Window
*
* @export
*/
export function WindowMaximise() {
window.runtime.WindowMaximise();
}
/**
* Unmaximise the Window
*
* @export
*/
export function WindowUnmaximise() {
window.runtime.WindowUnmaximise();
}
/**
* Minimise the Window
*
* @export
*/
export function WindowMinimise() {
window.runtime.WindowMinimise();
}
/**
* Unminimise the Window
*
* @export
*/
export function WindowUnminimise() {
window.runtime.WindowUnminimise();
}
/**
* Close the Window
*
* @export
*/
export function WindowClose() {
window.runtime.WindowClose();
}