diff --git a/RemoteDesktop/README.md b/RemoteDesktop/README.md
index c085aef..f616122 100644
--- a/RemoteDesktop/README.md
+++ b/RemoteDesktop/README.md
@@ -7,6 +7,8 @@ Further information on **wvnc**: [https://blog.lxsang.me/post/id/23](https://blo
## Change logs
+* v0.1.15 - Only send ACK command when finish rendering the received frame, this allows to vastly improve performance and bandwidth
+* v0.1.14 - Add toolbar for canvas size control
* v0.1.13 - support AntOS v2.0.x
* v0.1.12 - improve UI handling
* v0.1.11 - Support 16 bits per pixel
diff --git a/RemoteDesktop/assets/main.css b/RemoteDesktop/assets/main.css
index ecb3e43..4a806e6 100644
--- a/RemoteDesktop/assets/main.css
+++ b/RemoteDesktop/assets/main.css
@@ -1,6 +1,7 @@
afx-app-window[data-id="RemoteDesktop"] div[data-id="container"]
{
background-color: #272822;
+ overflow: hidden;
}
afx-app-window[data-id="RemoteDesktop"] canvas[data-id="screen"]
{
diff --git a/RemoteDesktop/assets/scheme.html b/RemoteDesktop/assets/scheme.html
index 08bbe4c..d038277 100644
--- a/RemoteDesktop/assets/scheme.html
+++ b/RemoteDesktop/assets/scheme.html
@@ -1,7 +1,17 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RemoteDesktop/build/debug/README.md b/RemoteDesktop/build/debug/README.md
index c085aef..f616122 100644
--- a/RemoteDesktop/build/debug/README.md
+++ b/RemoteDesktop/build/debug/README.md
@@ -7,6 +7,8 @@ Further information on **wvnc**: [https://blog.lxsang.me/post/id/23](https://blo
## Change logs
+* v0.1.15 - Only send ACK command when finish rendering the received frame, this allows to vastly improve performance and bandwidth
+* v0.1.14 - Add toolbar for canvas size control
* v0.1.13 - support AntOS v2.0.x
* v0.1.12 - improve UI handling
* v0.1.11 - Support 16 bits per pixel
diff --git a/RemoteDesktop/build/debug/main.css b/RemoteDesktop/build/debug/main.css
index ecb3e43..4a806e6 100644
--- a/RemoteDesktop/build/debug/main.css
+++ b/RemoteDesktop/build/debug/main.css
@@ -1,6 +1,7 @@
afx-app-window[data-id="RemoteDesktop"] div[data-id="container"]
{
background-color: #272822;
+ overflow: hidden;
}
afx-app-window[data-id="RemoteDesktop"] canvas[data-id="screen"]
{
diff --git a/RemoteDesktop/build/debug/main.js b/RemoteDesktop/build/debug/main.js
index 2d8801e..41afa34 100644
--- a/RemoteDesktop/build/debug/main.js
+++ b/RemoteDesktop/build/debug/main.js
@@ -1,770 +1 @@
-(function() {
- var ConnectionDialog, CredentialDialog, RemoteDesktop, WVNC;
-
- ConnectionDialog = class ConnectionDialog extends this.OS.GUI.BasicDialog {
- constructor() {
- super("ConnectionDialog", ConnectionDialog.scheme);
- }
-
- main() {
- super.main();
- this.find("bbp").data = [
- {
- text: "16 bits",
- value: 16,
- selected: true
- },
- {
- text: "32 bits",
- value: 32
- }
- ];
- this.find("jq").value = 40;
- this.find("bt-ok").onbtclick = (e) => {
- var data;
- if (!this.handle) {
- return;
- }
- data = {
- wvnc: (this.find("txtWVNC")).value,
- server: (this.find("txtServer")).value,
- bbp: (this.find("bbp")).selectedItem.data.value,
- quality: (this.find("jq")).value
- };
- this.handle(data);
- return this.quit();
- };
- return this.find("bt-cancel").onbtclick = (e) => {
- return this.quit();
- };
- }
-
- };
-
- ConnectionDialog.scheme = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
- CredentialDialog = class CredentialDialog extends this.OS.GUI.BasicDialog {
- constructor() {
- super("CredentialDialog", CredentialDialog.scheme);
- }
-
- main() {
- this.find("bt-ok").onbtclick = () => {
- var data;
- if (!this.handle) {
- return this.quit();
- }
- data = {
- username: (this.find("txtUser")).value,
- password: (this.find("txtPass")).value
- };
- this.handle(data);
- return this.quit();
- };
- return this.find("bt-cancel").onbtclick = () => {
- return this.quit();
- };
- }
-
- };
-
- CredentialDialog.scheme = `
-
-
-
-
-
-
-
-`;
-
- RemoteDesktop = class RemoteDesktop extends this.OS.application.BaseApplication {
- constructor(args) {
- super("RemoteDesktop", args);
- }
-
- main() {
- this.canvas = this.find("screen");
- this.container = this.find("container");
- this.client = new WVNC({
- element: this.canvas
- });
- this.bindKey("CTRL-SHIFT-V", (e) => {
- return this.pasteText();
- });
- //@client.onerror = (m) =>
- // @error m.toString()
- // @showConnectionDialog()
- this.client.ondisconnect = () => {
- return this.showConnectionDialog();
- };
- this.client.onresize = () => {
- return this.setScale();
- };
- this.client.onpassword = () => {
- return new Promise((r, e) => {
- return this.openDialog("PromptDialog", {
- title: __("VNC password"),
- label: __("VNC password"),
- value: "password",
- type: "password"
- }).then(function(d) {
- return r(d);
- });
- });
- };
- this.client.oncopy = (text) => {
- return this._api.setClipboard(text);
- };
- this.client.oncredential = () => {
- return new Promise((r, e) => {
- return this.openDialog(new CredentialDialog(), {
- title: __("User credential")
- }).then(function(d) {
- return r(d.username, d.password);
- });
- });
- };
- this.on("resize", (e) => {
- return this.setScale();
- });
- this.on("focus", (e) => {
- return $(this.canvas).focus();
- });
- return this.client.init().then(() => {
- return this.showConnectionDialog();
- });
- }
-
- pasteText() {
- var cb;
- if (!this.client) {
- return;
- }
- cb = (text) => {
- if (!(text && text !== "")) {
- return;
- }
- return this.client.sendTextAsClipboard(text);
- };
- return this._api.getClipboard().then((text) => {
- return cb(text);
- }).catch((e) => {
- this.error(__("Unable to paste"), e);
- //ask for user to enter the text manually
- return this.openDialog("TextDialog", {
- title: "Paste text"
- }).then((text) => {
- return cb(text);
- }).catch((err) => {
- return this.error(err.toString(), err);
- });
- });
- }
-
- setScale() {
- var h, sx, sy, w;
- if (!(this.client && this.client.resolution)) {
- return;
- }
- w = $(this.container).width();
- h = $(this.container).height();
- sx = w / this.client.resolution.w;
- sy = h / this.client.resolution.h;
- if (sx > sy) {
- return this.client.setScale(sy);
- } else {
- return this.client.setScale(sx);
- }
- }
-
- menu() {
- return [
- {
- text: "__(Connection)",
- nodes: [
- {
- text: "__(New Connection)",
- dataid: `${this.name}-new`
- },
- {
- text: "__(Disconnect)",
- dataid: `${this.name}-close`
- }
- ],
- onchildselect: (e) => {
- if (this.client) {
- return this.client.disconnect(false);
- }
- }
- }
- ];
- }
-
- showConnectionDialog() {
- if (!this.client) {
- return;
- }
- return this.openDialog(new ConnectionDialog(), {
- title: __("Connection")
- }).then((d) => {
- this.client.ws = d.wvnc;
- return this.client.connect(d.server, d);
- });
- }
-
- cleanup() {
- if (this.client) {
- this.client.disconnect(true);
- }
- return this.client = void 0;
- }
-
- };
-
- this.OS.register("RemoteDesktop", RemoteDesktop);
-
- WVNC = class WVNC {
- constructor(args) {
- var me, worker;
- this.socket = void 0;
- this.ws = void 0;
- this.canvas = void 0;
- worker = "pkg://RemoteDesktop/decoder_asm.js".asFileHandle().getlink();
- this.scale = 1.0;
- if (args.ws) {
- this.ws = args.ws;
- }
- this.canvas = args.element;
- if (typeof this.canvas === 'string') {
- this.canvas = document.getElementById(this.canvas);
- }
- this.decoder = new Worker(worker);
- this.enableEvent = false;
- this.pingto = false;
- me = this;
- this.mouseMask = 0;
- this.decoder.onmessage = function(e) {
- return me.process(e.data);
- };
- }
-
- init() {
- var me;
- me = this;
- return new Promise(function(r, e) {
- if (!me.canvas) {
- return e('Canvas is not set');
- }
- // fix keyboard event problem
- $(me.canvas).attr('tabindex', '1');
- $(me.canvas).on("focus", () => {
- return me.resetModifierKeys();
- });
- me.initInputEvent();
- return r();
- });
- }
-
- initInputEvent() {
- var fn, getMousePos, me, sendMouseLocation;
- me = this;
- if (!this.canvas) {
- return;
- }
- getMousePos = function(e) {
- var pos, rect;
- rect = me.canvas.getBoundingClientRect();
- pos = {
- x: Math.floor((e.clientX - rect.left) / me.scale),
- y: Math.floor((e.clientY - rect.top) / me.scale)
- };
- return pos;
- };
- sendMouseLocation = function(e) {
- var p;
- if (!me.enableEvent) {
- return;
- }
- p = getMousePos(e);
- return me.sendPointEvent(p.x, p.y, me.mouseMask);
- };
- if (!me.canvas) {
- return;
- }
- me.canvas.oncontextmenu = function(e) {
- e.preventDefault();
- return false;
- };
- me.canvas.onmousemove = function(e) {
- return sendMouseLocation(e);
- };
- me.canvas.onmousedown = function(e) {
- var state;
- state = 1 << e.button;
- me.mouseMask = me.mouseMask | state;
- return sendMouseLocation(e);
- };
- //e.preventDefault()
- me.canvas.onmouseup = function(e) {
- var state;
- state = 1 << e.button;
- me.mouseMask = me.mouseMask & (~state);
- return sendMouseLocation(e);
- };
- //e.preventDefault()
- me.canvas.onkeydown = me.canvas.onkeyup = function(e) {
- var code, keycode;
- // get the key code
- keycode = e.keyCode;
- //console.log e
- switch (keycode) {
- case 8:
- code = 0xFF08; //back space
- break;
- case 9:
- code = 0xFF09; // tab ? 0xff89
- break;
- case 13:
- code = 0xFF0D; // return
- break;
- case 27:
- code = 0xFF1B; // esc
- break;
- case 46:
- code = 0xFFFF; // delete to verify
- break;
- case 38:
- code = 0xFF52; // up
- break;
- case 40:
- code = 0xFF54; // down
- break;
- case 37:
- code = 0xFF51; // left
- break;
- case 39:
- code = 0xFF53; // right
- break;
- case 91:
- code = 0xFFE7; // meta left
- break;
- case 93:
- code = 0xFFE8; // meta right
- break;
- case 16:
- code = 0xFFE1; // shift left
- break;
- case 17:
- code = 0xFFE3; // ctrl left
- break;
- case 18:
- code = 0xFFE9; // alt left
- break;
- case 20:
- code = 0xFFE5; // capslock
- break;
- case 113:
- code = 0xFFBF; // f2
- break;
- case 112:
- code = 0xFFBE; // f1
- break;
- case 114:
- code = 0xFFC0; // f3
- break;
- case 115:
- code = 0xFFC1; // f4
- break;
- case 116:
- code = 0xFFC2; // f5
- break;
- case 117:
- code = 0xFFC3; // f6
- break;
- case 118:
- code = 0xFFC4; // f7
- break;
- case 119:
- code = 0xFFC5; // f8
- break;
- case 120:
- code = 0xFFC6; // f9
- break;
- case 121:
- code = 0xFFC7; // f10
- break;
- case 122:
- code = 0xFFC8; // f11
- break;
- case 123:
- code = 0xFFC9; // f12
- break;
- default:
- code = e.key.charCodeAt(0); //if not e.ctrlKey and not e.altKey
- }
- //if ((keycode > 47 and keycode < 58) or (keycode > 64 and keycode < 91) or (keycode > 95 and keycode < 112) or (keycode > 185 and keycode < 193) or (keycode > 218 && keycode < 223))
- // code = e.key.charCodeAt(0)
- //else
- // code = keycode
- e.preventDefault();
- if (!code) {
- return;
- }
- if (e.type === "keydown") {
- return me.sendKeyEvent(code, 1);
- } else if (e.type === "keyup") {
- return me.sendKeyEvent(code, 0);
- }
- };
- // mouse wheel event
- this.canvas.addEventListener('wheel', function(e) {
- var p;
- if (!me.enableEvent) {
- return;
- }
- //if (e.deltaY < 0) # up
- p = getMousePos(e);
- e.preventDefault();
- if (e.deltaY < 0) {
- me.sendPointEvent(p.x, p.y, 8);
- me.sendPointEvent(p.x, p.y, 0);
- return;
- }
- me.sendPointEvent(p.x, p.y, 16);
- return me.sendPointEvent(p.x, p.y, 0);
- });
- // paste event
- this.canvas.onpaste = function(e) {
- var pastedText;
- if (!me.enableEvent) {
- return;
- }
- pastedText = void 0;
- if (window.clipboardData && window.clipboardData.getData) { //IE
- pastedText = window.clipboardData.getData('Text');
- } else if (e.clipboardData && e.clipboardData.getData) {
- pastedText = e.clipboardData.getData('text/plain');
- }
- if (!pastedText) {
- return false;
- }
- e.preventDefault();
- return me.sendTextAsClipboard(pastedText);
- };
- // global event
- fn = (e) => {
- return this.disconnect(true);
- };
- window.addEventListener("unload", fn);
- return window.addEventListener("beforeunload", fn);
- }
-
- initCanvas(w, h, d) {
- var me;
- me = this;
- this.canvas.width = w;
- this.canvas.height = h;
- this.resolution = {
- w: w,
- h: h
- };
- this.decoder.postMessage(this.resolution);
- //me.canvas.style.cursor = "none"
- return this.setScale(this.scale);
- }
-
- process(msg) {
- var ctx, data, imgData;
- if (!this.socket) {
- this.socket.send(this.buildCommand(0x04, 1));
- return;
- }
- data = new Uint8Array(msg.pixels);
- ctx = this.canvas.getContext("2d", {
- alpha: false
- });
- imgData = ctx.createImageData(msg.w, msg.h);
- imgData.data.set(data);
- ctx.putImageData(imgData, msg.x, msg.y);
- // tell the server that we are ready
- return this.socket.send(this.buildCommand(0x04, 1));
- }
-
- setScale(n) {
- this.scale = n;
- if (!this.canvas) {
- return;
- }
- this.canvas.style.transformOrigin = '0 0';
- return this.canvas.style.transform = 'scale(' + n + ')';
- }
-
- connect(url, args) {
- var me;
- me = this;
- this.disconnect(false);
- if (!this.ws) {
- return;
- }
- this.socket = new WebSocket(this.ws);
- this.socket.binaryType = "arraybuffer";
- this.socket.onopen = function() {
- console.log("socket opened");
- return me.initConnection(url, args);
- };
- this.socket.onmessage = function(e) {
- return me.consume(e);
- };
- this.socket.onerror = (e) => {
- return me.onerror("Websocket error");
- };
- return this.socket.onclose = function() {
- me.socket = null;
- me.canvas.style.cursor = "auto";
- if (me.canvas && me.resolution) {
- me.canvas.getContext('2d').clearRect(0, 0, me.resolution.w, me.resolution.h);
- }
- if (me.pingto) {
- clearTimeout(me.pingto);
- }
- me.pingto = void 0;
- me.ondisconnect();
- return console.log("socket closed");
- };
- }
-
- disconnect(close_worker) {
- if (this.socket) {
- this.socket.close();
- }
- this.socket = void 0;
- if (close_worker) {
- this.decoder.terminate();
- }
- return this.enableEvent = false;
- }
-
- initConnection(vncserver, params) {
- var data;
- //vncserver = "192.168.1.20:5901"
- data = new Uint8Array(vncserver.length + 2);
- data[0] = 16; // bbp
- data[1] = 50; // jpeg quality
- if (params) {
- if (params.bbp) {
- data[0] = params.bbp;
- }
- if (params.quality) {
- data[1] = params.quality;
- }
- }
- //# rate in milisecond
- data.set((new TextEncoder()).encode(vncserver), 2);
- return this.socket.send(this.buildCommand(0x01, data));
- }
-
- resetModifierKeys() {
- if (!this.socket) {
- return;
- }
- if (!this.enableEvent) {
- return;
- }
- this.sendKeyEvent(0xFFE7, 0); // meta left
- this.sendKeyEvent(0xFFE8, 0); // meta right
- this.sendKeyEvent(0xFFE1, 0); // shift left
- this.sendKeyEvent(0xFFE3, 0); // ctrl left
- return this.sendKeyEvent(0xFFE9, 0); // alt left
- }
-
- sendPointEvent(x, y, mask) {
- var data;
- if (!this.socket) {
- return;
- }
- if (!this.enableEvent) {
- return;
- }
- data = new Uint8Array(5);
- data[0] = x & 0xFF;
- data[1] = x >> 8;
- data[2] = y & 0xFF;
- data[3] = y >> 8;
- data[4] = mask;
- return this.socket.send(this.buildCommand(0x05, data));
- }
-
- sendKeyEvent(code, v) {
- var data;
- // console.log code, v
- if (!this.socket) {
- return;
- }
- if (!this.enableEvent) {
- return;
- }
- data = new Uint8Array(3);
- data[0] = code & 0xFF;
- data[1] = (code >> 8) & 0xFF;
- data[2] = v;
- return this.socket.send(this.buildCommand(0x06, data));
- }
-
- sendPing() {
- if (!this.socket) {
- return;
- }
- return this.socket.send(this.buildCommand(0x08, 'PING WVNC'));
- }
-
- buildCommand(hex, o) {
- var cmd, data;
- data = void 0;
- switch (typeof o) {
- case 'string':
- data = (new TextEncoder()).encode(o);
- break;
- case 'number':
- data = new Uint8Array([o]);
- break;
- default:
- data = o;
- }
- cmd = new Uint8Array(data.length + 3);
- cmd[0] = hex;
- cmd[2] = data.length >> 8;
- cmd[1] = data.length & 0x0F;
- cmd.set(data, 3);
- //console.log "the command is", cmd.buffer
- return cmd.buffer;
- }
-
- oncopy(text) {
- return console.log("Get clipboard text: " + text);
- }
-
- onpassword() {
- return new Promise(function(resolve, reject) {
- return reject("onpassword is not implemented");
- });
- }
-
- sendTextAsClipboard(text) {
- var charcode;
- if (!this.socket) {
- return;
- }
- this.socket.send(this.buildCommand(0x07, text));
- // send ctrl-v to paste
- charcode = 'v'.charCodeAt(0);
- this.sendKeyEvent(0xFFE3, 1); // CTRL down
- this.sendKeyEvent(charcode, 1); // v down
- this.sendKeyEvent(charcode, 0); // v up
- return this.sendKeyEvent(0xFFE3, 0); // CTRL up
- }
-
- oncredential() {
- return new Promise(function(resolve, reject) {
- return reject("oncredential is not implemented");
- });
- }
-
- onerror(m) {
- return console.log("Error", m);
- }
-
- onresize() {
- return console.log("resize");
- }
-
- ondisconnect() {
- return console.log("disconnect");
- }
-
- consume(e) {
- var cmd, data, dec, fn, h, me, w;
- data = new Uint8Array(e.data);
- cmd = data[0];
- me = this;
- switch (cmd) {
- case 0xFE: //error
- data = data.subarray(1, data.length - 1);
- dec = new TextDecoder("utf-8");
- return this.onerror(dec.decode(data));
- case 0x81:
- console.log("Request for password");
- this.enableEvent = false;
- return this.onpassword().then(function(pass) {
- me.socket.send(me.buildCommand(0x02, pass));
- return me.enableEvent = true;
- });
- case 0x82:
- console.log("Request for login");
- this.enableEvent = false;
- return this.oncredential().then(function(user, pass) {
- var arr;
- arr = new Uint8Array(user.length + pass.length + 1);
- arr.set((new TextEncoder()).encode(user), 0);
- arr.set(['\0'], user.length);
- arr.set((new TextEncoder()).encode(pass), user.length + 1);
- me.socket.send(me.buildCommand(0x03, arr));
- return me.enableEvent = true;
- });
- case 0x83:
- w = data[1] | (data[2] << 8);
- h = data[3] | (data[4] << 8);
- this.initCanvas(w, h);
- // status command for ack
- this.socket.send(this.buildCommand(0x04, 1));
- this.enableEvent = true;
- // @resetModifierKeys()
- this.onresize();
- if (this.pingto) {
- return;
- }
- fn = () => {
- this.sendPing();
- return this.pingto = setTimeout(fn, 5000);
- };
- return this.pingto = setTimeout(fn, 5000);
- case 0x84:
- // send data to web assembly for decoding
- return this.decoder.postMessage(data.buffer, [data.buffer]);
- case 0x85:
- // clipboard data from server
- data = data.subarray(1);
- dec = new TextDecoder("utf-8");
- this.oncopy(dec.decode(data));
- return this.socket.send(this.buildCommand(0x04, 1));
- default:
- return console.log(cmd);
- }
- }
-
- };
-
- window.WVNC = WVNC;
-
-}).call(this);
+(function(){var e,t,n,s;(e=class e extends this.OS.GUI.BasicDialog{constructor(){super("ConnectionDialog",e.scheme)}main(){return super.main(),this.find("bbp").data=[{text:"16 bits",value:16,selected:!0},{text:"32 bits",value:32}],this.find("jq").value=40,this.find("bt-ok").onbtclick=e=>{var t;if(this.handle)return t={wvnc:this.find("txtWVNC").value,server:this.find("txtServer").value,bbp:this.find("bbp").selectedItem.data.value,quality:this.find("jq").value},this.handle(t),this.quit()},this.find("bt-cancel").onbtclick=e=>this.quit()}}).scheme='\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n',(t=class e extends this.OS.GUI.BasicDialog{constructor(){super("CredentialDialog",e.scheme)}main(){return this.find("bt-ok").onbtclick=()=>{var e;return this.handle?(e={username:this.find("txtUser").value,password:this.find("txtPass").value},this.handle(e),this.quit()):this.quit()},this.find("bt-cancel").onbtclick=()=>this.quit()}}).scheme='\n \n \n \n \n \n \n \n',n=class extends this.OS.application.BaseApplication{constructor(e){super("RemoteDesktop",e)}main(){return this.canvas=this.find("screen"),this.container=this.find("container"),this.zoom=this.find("zoom"),this.btreset=this.find("btreset"),this.zoom.max=200,this.zoom.value=100,this.zoom.onvaluechange=e=>this.setScale(),this.find("scroll_down").onbtclick=e=>this.container.scrollTop+=20,this.find("scroll_up").onbtclick=e=>this.container.scrollTop-=20,this.find("scroll_left").onbtclick=e=>this.container.scrollLeft-=20,this.find("scroll_right").onbtclick=e=>this.container.scrollLeft+=20,this.btreset.onbtclick=e=>{var t,n,s,i;return i=$(this.container).width(),t=$(this.container).height(),n=i/this.client.resolution.w,s=t/this.client.resolution.h,this.zoom.value=n>s?100*s:100*n,this.setScale()},this.client=new s({element:this.canvas}),this.bindKey("CTRL-SHIFT-V",e=>this.pasteText()),this.client.ondisconnect=()=>this.showConnectionDialog(),this.client.onresize=()=>this.setScale(),this.client.onpassword=()=>new Promise((e,t)=>this.openDialog("PromptDialog",{title:__("VNC password"),label:__("VNC password"),value:"password",type:"password"}).then((function(t){return e(t)}))),this.client.oncopy=e=>this._api.setClipboard(e),this.client.oncredential=()=>new Promise((e,n)=>this.openDialog(new t,{title:__("User credential")}).then((function(t){return e(t.username,t.password)}))),this.on("focus",e=>$(this.canvas).focus()),this.client.init().then(()=>this.showConnectionDialog())}pasteText(){var e;if(this.client)return e=e=>{if(e&&""!==e)return this.client.sendTextAsClipboard(e)},this._api.getClipboard().then(t=>e(t)).catch(t=>(this.error(__("Unable to paste"),t),this.openDialog("TextDialog",{title:"Paste text"}).then(t=>e(t)).catch(e=>this.error(e.toString(),e))))}setScale(){if(console.log("scale changed"),this.client&&this.client.resolution)return this.client.setScale(this.zoom.value/100),this.container.scrollLeft=0,this.container.scrollTop=0}menu(){return[{text:"__(Connection)",nodes:[{text:"__(New Connection)",dataid:this.name+"-new"},{text:"__(Disconnect)",dataid:this.name+"-close"}],onchildselect:e=>{if(this.client)return this.client.disconnect(!1)}}]}showConnectionDialog(){if(this.client)return this.openDialog(new e,{title:__("Connection")}).then(e=>(this.client.ws=e.wvnc,this.client.connect(e.server,e)))}cleanup(){return this.client&&this.client.disconnect(!0),this.client=void 0}},this.OS.register("RemoteDesktop",n),s=class{constructor(e){var t,n;this.socket=void 0,this.ws=void 0,this.canvas=void 0,n="pkg://RemoteDesktop/decoder_asm.js".asFileHandle().getlink(),this.scale=1,e.ws&&(this.ws=e.ws),this.canvas=e.element,"string"==typeof this.canvas&&(this.canvas=document.getElementById(this.canvas)),this.decoder=new Worker(n),this.enableEvent=!1,this.pingto=!1,t=this,this.mouseMask=0,this.decoder.onmessage=function(e){return t.process(e.data)}}init(){var e;return e=this,new Promise((function(t,n){return e.canvas?($(e.canvas).attr("tabindex","1"),$(e.canvas).on("focus",()=>e.resetModifierKeys()),e.initInputEvent(),t()):n("Canvas is not set")}))}initInputEvent(){var e,t,n,s;if(n=this,this.canvas&&(t=function(e){var t;return t=n.canvas.getBoundingClientRect(),{x:Math.floor((e.clientX-t.left)/n.scale),y:Math.floor((e.clientY-t.top)/n.scale)}},s=function(e){var s;if(n.enableEvent)return s=t(e),n.sendPointEvent(s.x,s.y,n.mouseMask)},n.canvas))return n.canvas.oncontextmenu=function(e){return e.preventDefault(),!1},n.canvas.onmousemove=function(e){return s(e)},n.canvas.onmousedown=function(e){var t;return t=1<this.disconnect(!0),window.addEventListener("unload",e),window.addEventListener("beforeunload",e)}initCanvas(e,t,n){return this.canvas.width=e,this.canvas.height=t,this.resolution={w:e,h:t},this.decoder.postMessage(this.resolution),this.setScale(this.scale)}process(e){var t,n,s;if(this.socket)return n=new Uint8Array(e.pixels),(s=(t=this.canvas.getContext("2d",{alpha:!1})).createImageData(e.w,e.h)).data.set(n),t.putImageData(s,e.x,e.y),this.socket.send(this.buildCommand(4,1));this.socket.send(this.buildCommand(4,1))}setScale(e){if(this.scale=e,this.canvas)return this.canvas.style.transformOrigin="0 0",this.canvas.style.transform="scale("+e+")"}connect(e,t){var n;if(n=this,this.disconnect(!1),this.ws)return this.socket=new WebSocket(this.ws),this.socket.binaryType="arraybuffer",this.socket.onopen=function(){return console.log("socket opened"),n.initConnection(e,t)},this.socket.onmessage=function(e){return n.consume(e)},this.socket.onerror=e=>n.onerror("Websocket error"),this.socket.onclose=function(){return n.socket=null,n.canvas.style.cursor="auto",n.canvas&&n.resolution&&n.canvas.getContext("2d").clearRect(0,0,n.resolution.w,n.resolution.h),n.pingto&&clearTimeout(n.pingto),n.pingto=void 0,n.ondisconnect(),console.log("socket closed")}}disconnect(e){return this.socket&&this.socket.close(),this.socket=void 0,e&&this.decoder.terminate(),this.enableEvent=!1}initConnection(e,t){var n;return(n=new Uint8Array(e.length+2))[0]=16,n[1]=50,t&&(t.bbp&&(n[0]=t.bbp),t.quality&&(n[1]=t.quality)),n.set((new TextEncoder).encode(e),2),this.socket.send(this.buildCommand(1,n))}resetModifierKeys(){if(this.socket&&this.enableEvent)return this.sendKeyEvent(65511,0),this.sendKeyEvent(65512,0),this.sendKeyEvent(65505,0),this.sendKeyEvent(65507,0),this.sendKeyEvent(65513,0)}sendPointEvent(e,t,n){var s;if(this.socket&&this.enableEvent)return(s=new Uint8Array(5))[0]=255&e,s[1]=e>>8,s[2]=255&t,s[3]=t>>8,s[4]=n,this.socket.send(this.buildCommand(5,s))}sendKeyEvent(e,t){var n;if(this.socket&&this.enableEvent)return(n=new Uint8Array(3))[0]=255&e,n[1]=e>>8&255,n[2]=t,this.socket.send(this.buildCommand(6,n))}sendPing(){if(this.socket)return this.socket.send(this.buildCommand(8,"PING WVNC"))}buildCommand(e,t){var n,s;switch(s=void 0,typeof t){case"string":s=(new TextEncoder).encode(t);break;case"number":s=new Uint8Array([t]);break;default:s=t}return(n=new Uint8Array(s.length+3))[0]=e,n[2]=s.length>>8,n[1]=15&s.length,n.set(s,3),n.buffer}oncopy(e){return console.log("Get clipboard text: "+e)}onpassword(){return new Promise((function(e,t){return t("onpassword is not implemented")}))}sendTextAsClipboard(e){var t;if(this.socket)return this.socket.send(this.buildCommand(7,e)),t="v".charCodeAt(0),this.sendKeyEvent(65507,1),this.sendKeyEvent(t,1),this.sendKeyEvent(t,0),this.sendKeyEvent(65507,0)}oncredential(){return new Promise((function(e,t){return t("oncredential is not implemented")}))}onerror(e){return console.log("Error",e)}onresize(){return console.log("resize")}ondisconnect(){return console.log("disconnect")}consume(e){var t,n,s,i,a,o,r;switch(t=(n=new Uint8Array(e.data))[0],o=this,t){case 254:return n=n.subarray(1,n.length-1),s=new TextDecoder("utf-8"),this.onerror(s.decode(n));case 129:return console.log("Request for password"),this.enableEvent=!1,this.onpassword().then((function(e){return o.socket.send(o.buildCommand(2,e)),o.enableEvent=!0}));case 130:return console.log("Request for login"),this.enableEvent=!1,this.oncredential().then((function(e,t){var n;return(n=new Uint8Array(e.length+t.length+1)).set((new TextEncoder).encode(e),0),n.set(["\0"],e.length),n.set((new TextEncoder).encode(t),e.length+1),o.socket.send(o.buildCommand(3,n)),o.enableEvent=!0}));case 131:if(r=n[1]|n[2]<<8,a=n[3]|n[4]<<8,this.initCanvas(r,a),this.socket.send(this.buildCommand(4,1)),this.enableEvent=!0,this.onresize(),this.pingto)return;return i=()=>(this.sendPing(),this.pingto=setTimeout(i,5e3)),this.pingto=setTimeout(i,5e3);case 132:return this.decoder.postMessage(n.buffer,[n.buffer]);case 133:return n=n.subarray(1),s=new TextDecoder("utf-8"),this.oncopy(s.decode(n)),this.socket.send(this.buildCommand(4,1));default:return console.log(t)}}},window.WVNC=s}).call(this);
\ No newline at end of file
diff --git a/RemoteDesktop/build/debug/package.json b/RemoteDesktop/build/debug/package.json
index d39faba..d1c46be 100644
--- a/RemoteDesktop/build/debug/package.json
+++ b/RemoteDesktop/build/debug/package.json
@@ -7,7 +7,7 @@
"author": "Dany LE",
"email": "contact@iohub.dev"
},
- "version":"0.1.13-b",
+ "version":"0.1.15-b",
"dependencies": [],
"category":"Internet",
"icon": "icon.png",
diff --git a/RemoteDesktop/build/debug/scheme.html b/RemoteDesktop/build/debug/scheme.html
index 08bbe4c..d038277 100644
--- a/RemoteDesktop/build/debug/scheme.html
+++ b/RemoteDesktop/build/debug/scheme.html
@@ -1,7 +1,17 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RemoteDesktop/build/release/RemoteDesktop.zip b/RemoteDesktop/build/release/RemoteDesktop.zip
index 2b913a1..770dbd8 100644
Binary files a/RemoteDesktop/build/release/RemoteDesktop.zip and b/RemoteDesktop/build/release/RemoteDesktop.zip differ
diff --git a/RemoteDesktop/coffees/main.coffee b/RemoteDesktop/coffees/main.coffee
index 36ba28e..2c67497 100644
--- a/RemoteDesktop/coffees/main.coffee
+++ b/RemoteDesktop/coffees/main.coffee
@@ -57,7 +57,6 @@ class CredentialDialog extends this.OS.GUI.BasicDialog
password: (@find "txtPass").value
@handle data
@quit()
-
@find("bt-cancel").onbtclick = () =>
@quit()
@@ -83,6 +82,29 @@ class RemoteDesktop extends this.OS.application.BaseApplication
main: () ->
@canvas = @find "screen"
@container = @find "container"
+ @zoom = @find "zoom"
+ @btreset = @find "btreset"
+ @zoom.max = 200
+ @zoom.value = 100
+ @zoom.onvaluechange = (e) => @setScale()
+ @find("scroll_down").onbtclick = (e) =>
+ @container.scrollTop += 20
+ @find("scroll_up").onbtclick = (e) =>
+ @container.scrollTop -= 20
+ @find("scroll_left").onbtclick = (e) =>
+ @container.scrollLeft -= 20
+ @find("scroll_right").onbtclick = (e) =>
+ @container.scrollLeft += 20
+ @btreset.onbtclick = (e) =>
+ w = $(@container).width()
+ h = $(@container).height()
+ sx = w / @client.resolution.w
+ sy = h / @client.resolution.h
+ if sx > sy
+ @zoom.value = sy*100
+ else
+ @zoom.value = sx*100
+ @setScale()
@client = new WVNC {
element: @canvas
}
@@ -113,7 +135,7 @@ class RemoteDesktop extends this.OS.application.BaseApplication
@openDialog new CredentialDialog, { title: __("User credential") }
.then (d) ->
r(d.username, d.password)
- @on "resize", (e)=> @setScale()
+ # @on "resize", (e)=> @setScale()
@on "focus", (e) => $(@canvas).focus()
@client.init().then () =>
@showConnectionDialog()
@@ -136,12 +158,11 @@ class RemoteDesktop extends this.OS.application.BaseApplication
.catch (err) => @error err.toString(), err
setScale: () ->
+ console.log "scale changed"
return unless @client and @client.resolution
- w = $(@container).width()
- h = $(@container).height()
- sx = w / @client.resolution.w
- sy = h / @client.resolution.h
- if sx > sy then @client.setScale sy else @client.setScale sx
+ @client.setScale @zoom.value / 100.0
+ @container.scrollLeft = 0
+ @container.scrollTop = 0
menu: () ->
diff --git a/RemoteDesktop/package.json b/RemoteDesktop/package.json
index d39faba..d1c46be 100644
--- a/RemoteDesktop/package.json
+++ b/RemoteDesktop/package.json
@@ -7,7 +7,7 @@
"author": "Dany LE",
"email": "contact@iohub.dev"
},
- "version":"0.1.13-b",
+ "version":"0.1.15-b",
"dependencies": [],
"category":"Internet",
"icon": "icon.png",
diff --git a/packages.json b/packages.json
index da4cab1..d74ea52 100644
--- a/packages.json
+++ b/packages.json
@@ -365,7 +365,7 @@
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/RemoteDesktop/README.md",
"category": "Internet",
"author": "Dany LE",
- "version": "0.1.13-b",
+ "version": "0.1.15-b",
"dependencies": [],"category":"Internet","icon":"icon.png","mimes":["none"],
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/2.0.x/RemoteDesktop/build/release/RemoteDesktop.zip"
},