1 | /**
|
2 | * Contains relevant code for creating and scaling Guacamole display
|
3 | */
|
4 | import Vue from 'vue'
|
5 | export default {
|
6 | name: 'GuacDisplay',
|
7 | methods: {
|
8 |
|
9 | /**
|
10 | * Adjust the scale of the connection display
|
11 | *
|
12 | * Requires Display to be initialized and autoScale option
|
13 | * to be set to True
|
14 | *
|
15 | * Determines the ideal scale to fit the display vertically and horizontally
|
16 | * and selects the smaller of the two values.
|
17 | */
|
18 | adjustScale () {
|
19 | if (!this.display) return
|
20 | if (!this.options.autoScale) return
|
21 |
|
22 | const element = this.$refs.displayWrapper
|
23 |
|
24 | if (!element) return
|
25 |
|
26 | const hScale = element.offsetWidth / this.display.getWidth()
|
27 | const vScale = element.offsetHeight / this.display.getHeight()
|
28 | const scale = Math.min(hScale, vScale)
|
29 | Vue.set(this.options, 'scale', scale)
|
30 | this.setScaledMouseState(scale)
|
31 | },
|
32 |
|
33 | /**
|
34 | * Creates the display for given connection
|
35 | *
|
36 | * Adds event listener to the window so that on resize it will attempt to
|
37 | * rescale the display
|
38 | */
|
39 | getDisplay () {
|
40 | // Add client to display div
|
41 | this.display = this.client.getDisplay()
|
42 | this.$refs.display.appendChild(this.client.getDisplay().getElement())
|
43 |
|
44 | window.addEventListener('resize', this.adjustScale)
|
45 | }
|
46 | },
|
47 | mounted(){
|
48 | try{
|
49 | // Checks for changes in visibility. May not be supported in Safari and older browsers
|
50 | const observer = new IntersectionObserver( (entries) => {
|
51 | if (entries[0].intersectionRatio){
|
52 | this.adjustScale()
|
53 | }
|
54 | }, {root: document.viewport})
|
55 |
|
56 | observer.observe(this.$refs.display)
|
57 | }catch (e) {
|
58 | // Do Nothing
|
59 | }
|
60 |
|
61 | try{
|
62 | // Additional observer to support Safari
|
63 | const pane = this.$refs.display.closest('.tab-pane')
|
64 | const safariObeserver = new MutationObserver( () => {
|
65 |
|
66 | if (pane.style.display !== 'none') {
|
67 | this.adjustScale()
|
68 | }
|
69 | })
|
70 |
|
71 | safariObeserver.observe(pane, { attributes: true, childList: true })
|
72 | }catch(e){
|
73 | // Nothing
|
74 | }
|
75 |
|
76 | },
|
77 | watch: {
|
78 | /**
|
79 | * Watches for change in autoScale option.
|
80 | * When enabling autoScale it will trigger a scale adjustment
|
81 | */
|
82 | 'options.autoScale': function (autoScale) {
|
83 | if (autoScale) {
|
84 | this.adjustScale()
|
85 | }
|
86 | },
|
87 |
|
88 | 'options.scale': function (scale) {
|
89 | this.setScaledMouseState(scale)
|
90 | },
|
91 |
|
92 | /**
|
93 | * When client state changes to 'CONNECTED' the display is
|
94 | * in the final steps of initializing. Attempting to auto-scale
|
95 | * the display at this point can cause the scale to be way off as the
|
96 | * element has not fully been constructed.
|
97 | *
|
98 | * Deferring the auto-scaling allows the display to be built on slower
|
99 | * connections and still be scaled appropriately
|
100 | */
|
101 | 'options.clientState': function (clientState) {
|
102 | if (clientState === 'CONNECTED') {
|
103 | setTimeout(this.adjustScale, 1000)
|
104 | }
|
105 | }
|
106 |
|
107 | }
|
108 | }
|