UNPKG

6.7 kBJavaScriptView Raw
1/**
2 * Contains code relevant to handling mouse, keyboard,
3 * and clipboard input for a Guacamole connection
4 */
5
6import Guacamole from 'guacamole-common-js'
7
8export default{
9
10 methods: {
11
12 /**
13 * Initializes the mouse event handlers and ties it to a display
14 */
15 initMouse () {
16 this.mouse = new Guacamole.Mouse(this.client.getDisplay().getElement())
17 this.mouse.onmousedown = this.mouse.onmouseup = this.mouse.onmousemove = (mouseState) => {
18 this.updateActivity()
19 this.client.sendMouseState(mouseState)
20 }
21
22 // let oldEvent = this.mouse.fromClientPosition
23 // this.mouse.fromClientPosition = function(element, clientX, clientY) {
24 // console.log("here")
25 // oldEvent(element, clientX, clientY)
26 // }
27 },
28
29 /**
30 * Initializes the keyboard event handlers and ties it to the document
31 *
32 * The document is the preferred method for the event handlers,
33 * but can cause some trouble if not careful. All input for the tab will be
34 * directed to this connection while these event handlers are in place. When
35 * wanting to not redirect the input to the VM (when the options drawer is open for instance)
36 * the event handlers will need to be nullified
37 */
38 initKeyboard () {
39 this.keyboard = new Guacamole.Keyboard(document);
40
41 if (!this.options.showOptionsDrawer && this.viewState !== 'thumbnail') {
42 this.keyboard.onkeydown = (keysym) => this.client.sendKeyEvent(1, keysym)
43 this.keyboard.onkeyup = (keysym) => this.client.sendKeyEvent(0, keysym)
44 } else {
45 this.keyboard.onkeydown = null
46 this.keyboard.onkeyup = null
47 }
48 },
49
50 /**
51 * Initializes the clipboard event handlers
52 *
53 * These event handlers will watch for changes to the VM clipboard and fire when
54 * those changes are detected. The value of the clipboard is saved in the options object.
55 */
56 initClipboard () {
57 this.client.onclipboard = (stream, mimetype) => {
58 // Only text/plain is supported for now
59 if (mimetype !== 'text/plain') {
60 stream.sendAck('Only text/plain supported', Guacamole.Status.Code.UNSUPPORTED)
61 return
62 }
63
64 var reader = new Guacamole.StringReader(stream)
65 var data = ''
66
67 // Append any received data to buffer
68 reader.ontext = (text) => {
69 data += text
70 stream.sendAck('Received', Guacamole.Status.Code.SUCCESS)
71 }
72
73 // Update state when done
74 reader.onend = () => {
75 this.options.clipboard = data
76 }
77 }
78 },
79
80 /**
81 * Sets the clipboard of the VM to the value found in the clipboard
82 * property of the options object
83 *
84 * Used to inject clipboard data to the VM
85 */
86 setClipboard () {
87
88 const stream = this.client.createClipboardStream()
89 const writer = new Guacamole.StringWriter(stream)
90
91 // Send text chunks
92 for (let i = 0; i < this.options.clipboard.length; i += 4096) {
93 writer.sendText(this.options.clipboard.substring(i, i + 4096))
94 }
95 // Close stream
96 writer.sendEnd()
97 },
98
99 /**
100 * Updates the mouse event listeners to correctly use the current scale of the display
101 *
102 * With out this the remote mouse and the local mouse will be offset based on the scale of the display
103 */
104 setScaledMouseState (scale) {
105 this.display.scale(scale)
106 this.mouse.onmousedown = this.mouse.onmouseup = this.mouse.onmousemove = (mouseState) => {
107 // Scale event by current scale
108 const scaledState = new Guacamole.Mouse.State(
109 mouseState.x / scale,
110 mouseState.y / scale,
111 mouseState.left,
112 mouseState.middle,
113 mouseState.right,
114 mouseState.up,
115 mouseState.down
116 )
117 this.updateActivity()
118 this.scrollToMouse(mouseState)
119
120 this.client.sendMouseState(scaledState)
121 }
122 },
123
124 /**
125 * Scrolls the client view such that the mouse cursor is visible.
126 *
127 * @param {Guacamole.Mouse.State} mouseState The current mouse
128 * state.
129 */
130 scrollToMouse (mouseState) {
131 const displayContainer = this.$refs.displayWrapper
132 const main = this.$refs.display
133
134 // Determine mouse position within view
135 const mouseViewX = mouseState.x + displayContainer.offsetLeft - main.scrollLeft
136 const mouseViewY = mouseState.y + displayContainer.offsetTop - main.scrollTop
137 // Determine viewport dimensions
138 const viewWidth = main.offsetWidth
139 const viewHeight = main.offsetHeight
140
141 // Determine scroll amounts based on mouse position relative to document
142
143 let scrollAmountX
144 if (mouseViewX > viewWidth) {
145 scrollAmountX = mouseViewX - viewWidth
146 } else if (mouseViewX < 0) {
147 scrollAmountX = mouseViewX
148 } else {
149 scrollAmountX = 0
150 }
151
152 let scrollAmountY
153 if (mouseViewY > viewHeight) {
154 scrollAmountY = mouseViewY - viewHeight
155 } else if (mouseViewY < 0) {
156 scrollAmountY = mouseViewY
157 } else {
158 scrollAmountY = 0
159 }
160 // Scroll (if necessary) to keep mouse on screen.
161 main.scrollLeft += scrollAmountX
162 main.scrollTop += scrollAmountY
163 }
164 },
165
166 beforeDestroy () {
167 if (this.keyboard){
168 this.keyboard.onkeydown = null
169 this.keyboard.onkeyup = null
170 }
171 },
172
173 watch: {
174 /**
175 * Removes the event handlers for the keyboard when options drawer
176 * is displayed
177 *
178 * Restores keyboard event handlers when options drawer is closed
179 */
180 'options.showOptionsDrawer': function (showOptionsDrawer) {
181 if (!this.keyboard) return
182
183 if (!showOptionsDrawer) {
184 this.keyboard.onkeydown = (keysym) => this.client.sendKeyEvent(1, keysym)
185 this.keyboard.onkeyup = (keysym) => this.client.sendKeyEvent(0, keysym)
186 } else {
187 this.keyboard.onkeydown = null
188 this.keyboard.onkeyup = null
189 }
190 },
191
192 /**
193 * Removes the event handlers for the keyboard when options drawer
194 * is displayed
195 *
196 * Restores keyboard event handlers when options drawer is closed
197 */
198 'viewState': function (viewState) {
199 if (!this.keyboard) return
200
201 if (!(viewState === 'thumbnail')) {
202 this.keyboard.onkeydown = (keysym) => {
203 this.updateActivity()
204 this.client.sendKeyEvent(1, keysym)
205 }
206 this.keyboard.onkeyup = (keysym) => this.client.sendKeyEvent(0, keysym)
207 } else {
208 this.keyboard.onkeydown = null
209 this.keyboard.onkeyup = null
210 }
211 }
212 }
213}