diff --git a/guacamole/src/main/webapp/app/client/directives/guacViewport.js b/guacamole/src/main/webapp/app/client/directives/guacViewport.js index 5f8269dce..d14a70a5e 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacViewport.js +++ b/guacamole/src/main/webapp/app/client/directives/guacViewport.js @@ -32,8 +32,7 @@ angular.module('client').directive('guacViewport', [function guacViewport() { function guacViewportController($scope, $injector, $element) { // Required services - var $window = $injector.get('$window'); - var $document = $injector.get('$document'); + var $window = $injector.get('$window'); /** * The fullscreen container element. @@ -43,18 +42,22 @@ angular.module('client').directive('guacViewport', [function guacViewport() { var element = $element.find('.viewport')[0]; /** - * The main document object. - * - * @type Document - */ - var document = $document[0]; - - /** - * The current adjusted height of the viewport element, if any. + * The width of the browser viewport when fitVisibleArea() was last + * invoked, in pixels, or null if fitVisibleArea() has not yet been + * called. * * @type Number */ - var currentAdjustedHeight = null; + var lastViewportWidth = null; + + /** + * The height of the browser viewport when fitVisibleArea() was + * last invoked, in pixels, or null if fitVisibleArea() has not yet + * been called. + * + * @type Number + */ + var lastViewportHeight = null; /** * Resizes the container element inside the guacViewport such that @@ -63,31 +66,32 @@ angular.module('client').directive('guacViewport', [function guacViewport() { */ var fitVisibleArea = function fitVisibleArea() { - // Pull scroll properties - var scrollLeft = document.body.scrollLeft; - var scrollTop = document.body.scrollTop; - var scrollWidth = document.body.scrollWidth; - var scrollHeight = document.body.scrollHeight; - - // Calculate new height - var adjustedHeight = scrollHeight - scrollTop; - - // Only update if not in response to our own call to scrollTo() - if (scrollLeft !== scrollWidth && scrollTop !== scrollHeight - && currentAdjustedHeight !== adjustedHeight) { - - // Adjust element to fit exactly within visible area - element.style.height = adjustedHeight + 'px'; - currentAdjustedHeight = adjustedHeight; - - // Scroll to bottom - $window.scrollTo(scrollWidth, scrollHeight); + // Calculate viewport dimensions (this is NOT necessarily the + // same as 100vw and 100vh, 100%, etc., particularly when the + // on-screen keyboard of a mobile device pops open) + var viewportWidth = $window.innerWidth; + var viewportHeight = $window.innerHeight; + // Adjust element width to fit exactly within visible area + if (viewportWidth !== lastViewportWidth) { + element.style.width = viewportWidth + 'px'; + lastViewportWidth = viewportWidth; } - // Manually attempt scroll if height has not been adjusted - else if (adjustedHeight === 0) - $window.scrollTo(scrollWidth, scrollHeight); + // Adjust element height to fit exactly within visible area + if (viewportHeight !== lastViewportHeight) { + element.style.height = viewportHeight + 'px'; + lastViewportHeight = viewportHeight; + } + + // Scroll element such that its upper-left corner is exactly + // within the viewport upper-left corner, if not already there + if (element.scrollLeft || element.scrollTop) { + $window.scrollTo( + $window.pageXOffset + element.scrollLeft, + $window.pageYOffset + element.scrollTop + ); + } }; diff --git a/guacamole/src/main/webapp/app/client/styles/keyboard.css b/guacamole/src/main/webapp/app/client/styles/keyboard.css index e5bb96317..5bf38889a 100644 --- a/guacamole/src/main/webapp/app/client/styles/keyboard.css +++ b/guacamole/src/main/webapp/app/client/styles/keyboard.css @@ -19,7 +19,6 @@ .keyboard-container { - display: none; text-align: center; width: 100%; @@ -33,7 +32,3 @@ z-index: 1; } - -.keyboard-container.open { - display: block; -} \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/client/styles/text-input.css b/guacamole/src/main/webapp/app/client/styles/text-input.css deleted file mode 100644 index 28e905ef4..000000000 --- a/guacamole/src/main/webapp/app/client/styles/text-input.css +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -.text-input-container { - display: none; -} - -.text-input-container.open { - display: block; -} diff --git a/guacamole/src/main/webapp/app/client/styles/viewport.css b/guacamole/src/main/webapp/app/client/styles/viewport.css index 9b43e0280..f1bf157c5 100644 --- a/guacamole/src/main/webapp/app/client/styles/viewport.css +++ b/guacamole/src/main/webapp/app/client/styles/viewport.css @@ -20,7 +20,7 @@ .viewport { position: absolute; bottom: 0; - left: 0; + right: 0; width: 100%; height: 100%; overflow: hidden; diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 5325b478e..1270efc38 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -22,12 +22,12 @@
-
- +
+
-
+
diff --git a/guacamole/src/main/webapp/app/textInput/directives/guacKey.js b/guacamole/src/main/webapp/app/textInput/directives/guacKey.js index e13e3f9c7..45fa4b38f 100644 --- a/guacamole/src/main/webapp/app/textInput/directives/guacKey.js +++ b/guacamole/src/main/webapp/app/textInput/directives/guacKey.js @@ -78,8 +78,12 @@ angular.module('textInput').directive('guacKey', [function guacKey() { * and keyup events. In the case of sticky keys, the pressed state * is toggled, and only a single keydown/keyup event will be sent, * depending on the current state. + * + * @param {MouseEvent} event + * The mouse event which resulted in this function being + * invoked. */ - $scope.updateKey = function updateKey() { + $scope.updateKey = function updateKey(event) { // If sticky, toggle pressed state if ($scope.sticky) @@ -91,6 +95,9 @@ angular.module('textInput').directive('guacKey', [function guacKey() { $rootScope.$broadcast('guacSyntheticKeyup', $scope.keysym); } + // Prevent loss of focus due to interaction with buttons + event.preventDefault(); + }; // Send keyup/keydown when pressed state is altered diff --git a/guacamole/src/main/webapp/app/textInput/directives/guacTextInput.js b/guacamole/src/main/webapp/app/textInput/directives/guacTextInput.js index 3a4ac2090..c1a467727 100644 --- a/guacamole/src/main/webapp/app/textInput/directives/guacTextInput.js +++ b/guacamole/src/main/webapp/app/textInput/directives/guacTextInput.js @@ -25,17 +25,7 @@ angular.module('textInput').directive('guacTextInput', [function guacTextInput() return { restrict: 'E', replace: true, - scope: { - - /** - * Whether the text input UI should have focus. Setting this value - * is not guaranteed to work, due to browser limitations. - * - * @type Boolean - */ - needsFocus : '=?' - - }, + scope: {}, templateUrl: 'app/textInput/templates/guacTextInput.html', controller: ['$scope', '$rootScope', '$element', '$timeout', @@ -144,7 +134,6 @@ angular.module('textInput').directive('guacTextInput', [function guacTextInput() target.onblur = function targetFocusLost() { hasFocus = false; - target.focus(); }; /** @@ -331,16 +320,6 @@ angular.module('textInput').directive('guacTextInput', [function guacTextInput() e.preventDefault(); }, false); - // Attempt to change focus depending on need - $scope.$watch('needsFocus', function focusDesireChanged(focusNeeded) { - - if (focusNeeded) - target.focus(); - else - target.blur(); - - }); - // If the text input UI has focus, prevent keydown events $scope.$on('guacBeforeKeydown', function filterKeydown(event, keysym) { if (hasFocus && !ALLOWED_KEYS[keysym]) @@ -353,6 +332,9 @@ angular.module('textInput').directive('guacTextInput', [function guacTextInput() event.preventDefault(); }); + // Attempt to focus initially + target.focus(); + }] }; diff --git a/guacamole/src/main/webapp/app/textInput/styles/textInput.css b/guacamole/src/main/webapp/app/textInput/styles/textInput.css index 2d6a820d3..08c0a7e99 100644 --- a/guacamole/src/main/webapp/app/textInput/styles/textInput.css +++ b/guacamole/src/main/webapp/app/textInput/styles/textInput.css @@ -18,26 +18,36 @@ */ .text-input { + + display: -webkit-box; + display: -webkit-flex; + display: -moz-box; + display: -ms-flexbox; + display: flex; + + -webkit-box-align: center; + -webkit-align-items: center; + -moz-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; background: #222; color: white; -} -.text-input .text-input-field, -.text-input .text-input-buttons { - display: inline-block; - vertical-align: middle; } .text-input .text-input-field { - width: 30%; - overflow: hidden; - white-space: nowrap; + -webkit-box-flex: 1; + -webkit-flex: 1; + -moz-box-flex: 1; + -ms-flex: 1; + flex: 1; } -.text-input .text-input-buttons { - width: 70%; - text-align: right; +.text-input .text-input-field { + overflow: hidden; + white-space: nowrap; } .text-input .target { @@ -62,10 +72,6 @@ } -.text-input.open { - display: block; -} - .text-input .sent-history { display: inline-block; vertical-align: middle; diff --git a/guacamole/src/main/webapp/app/textInput/templates/guacKey.html b/guacamole/src/main/webapp/app/textInput/templates/guacKey.html index 61c96726f..acd6f5a95 100644 --- a/guacamole/src/main/webapp/app/textInput/templates/guacKey.html +++ b/guacamole/src/main/webapp/app/textInput/templates/guacKey.html @@ -1,4 +1,3 @@ - diff --git a/guacamole/src/main/webapp/app/textInput/templates/guacTextInput.html b/guacamole/src/main/webapp/app/textInput/templates/guacTextInput.html index cb1c8375f..7b8b72881 100644 --- a/guacamole/src/main/webapp/app/textInput/templates/guacTextInput.html +++ b/guacamole/src/main/webapp/app/textInput/templates/guacTextInput.html @@ -1,6 +1,6 @@
-
{{text}}
+
{{text}}