noVNC: make show dot configurable (#11741)

diff --git a/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java
index 5981993..7b5fc12 100644
--- a/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java
+++ b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManager.java
@@ -56,6 +56,10 @@
     ConfigKey<Boolean> NoVncConsoleSourceIpCheckEnabled = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class, "novnc.console.sourceip.check.enabled", "false",
         "If true, The source IP to access novnc console must be same as the IP in request to management server for console URL. Needs to reconnect CPVM to management server when this changes (via restart CPVM, or management server, or cloud service in CPVM)", false);
 
+    ConfigKey<Boolean> NoVncConsoleShowDot = new ConfigKey<>(Boolean.class, "novnc.console.show.dot", ConfigKey.CATEGORY_ADVANCED, "true",
+            "If true, in noVNC console a dot cursor will be shown when the remote server provides no local cursor, or provides a fully-transparent (invisible) cursor.",
+            true, ConfigKey.Scope.Zone, null);
+
     ConfigKey<String> ConsoleProxyServiceOffering = new ConfigKey<>(String.class, "consoleproxy.service.offering", "Console Proxy", null,
             "Uuid of the service offering used by console proxy; if NULL - system offering will be used", true, ConfigKey.Scope.Zone, null);
 
diff --git a/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 98fa8a4..c273cf4 100644
--- a/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/main/java/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -1572,7 +1572,7 @@
     public ConfigKey<?>[] getConfigKeys() {
         return new ConfigKey<?>[] { ConsoleProxySslEnabled, NoVncConsoleDefault, NoVncConsoleSourceIpCheckEnabled, ConsoleProxyServiceOffering,
                 ConsoleProxyCapacityStandby, ConsoleProxyCapacityScanInterval, ConsoleProxyCmdPort, ConsoleProxyRestart, ConsoleProxyUrlDomain, ConsoleProxySessionMax, ConsoleProxySessionTimeout, ConsoleProxyDisableRpFilter, ConsoleProxyLaunchMax,
-                ConsoleProxyManagementLastState, ConsoleProxyServiceManagementState };
+                ConsoleProxyManagementLastState, ConsoleProxyServiceManagementState, NoVncConsoleShowDot };
     }
 
     protected ConsoleProxyStatus parseJsonToConsoleProxyStatus(String json) throws JsonParseException {
diff --git a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
index fde9377..237135b 100644
--- a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
@@ -89,6 +89,8 @@
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
+import static com.cloud.consoleproxy.ConsoleProxyManager.NoVncConsoleShowDot;
+
 public class ConsoleAccessManagerImpl extends ManagerBase implements ConsoleAccessManager {
 
     @Inject
@@ -565,8 +567,9 @@
         if (param.getHypervHost() != null || !ConsoleProxyManager.NoVncConsoleDefault.value()) {
             sb.append("/ajax?token=").append(token);
         } else {
+            String showDot = NoVncConsoleShowDot.valueIn(vm.getDataCenterId()) ? "true" : "false";
             sb.append("/resource/noVNC/vnc.html")
-                    .append("?autoconnect=true&show_dot=true")
+                    .append("?autoconnect=true&show_dot=").append(showDot)
                     .append("&port=").append(vncPort)
                     .append("&token=").append(token);
             if (requiresVncOverWebSocketConnection(vm, hostVo) && StringUtils.isNotBlank(locale)) {