/ src / settings-ui / Settings.UI / ViewModels / MouseUtilsViewModel.cs
MouseUtilsViewModel.cs
   1  // Copyright (c) Microsoft Corporation
   2  // The Microsoft Corporation licenses this file to you under the MIT license.
   3  // See the LICENSE file in the project root for more information.
   4  
   5  using System;
   6  using System.Collections.Generic;
   7  using System.ComponentModel;
   8  using System.Runtime.CompilerServices;
   9  using global::PowerToys.GPOWrapper;
  10  using Microsoft.PowerToys.Settings.UI.Helpers;
  11  using Microsoft.PowerToys.Settings.UI.Library;
  12  using Microsoft.PowerToys.Settings.UI.Library.Helpers;
  13  using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
  14  using Microsoft.PowerToys.Settings.Utilities;
  15  
  16  namespace Microsoft.PowerToys.Settings.UI.ViewModels
  17  {
  18      public partial class MouseUtilsViewModel : PageViewModelBase
  19      {
  20          protected override string ModuleName => "MouseUtils";
  21  
  22          private SettingsUtils SettingsUtils { get; set; }
  23  
  24          private GeneralSettings GeneralSettingsConfig { get; set; }
  25  
  26          private FindMyMouseSettings FindMyMouseSettingsConfig { get; set; }
  27  
  28          private MouseHighlighterSettings MouseHighlighterSettingsConfig { get; set; }
  29  
  30          private MousePointerCrosshairsSettings MousePointerCrosshairsSettingsConfig { get; set; }
  31  
  32          private CursorWrapSettings CursorWrapSettingsConfig { get; set; }
  33  
  34          public MouseUtilsViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FindMyMouseSettings> findMyMouseSettingsRepository, ISettingsRepository<MouseHighlighterSettings> mouseHighlighterSettingsRepository, ISettingsRepository<MouseJumpSettings> mouseJumpSettingsRepository, ISettingsRepository<MousePointerCrosshairsSettings> mousePointerCrosshairsSettingsRepository, ISettingsRepository<CursorWrapSettings> cursorWrapSettingsRepository, Func<string, int> ipcMSGCallBackFunc)
  35          {
  36              SettingsUtils = settingsUtils;
  37  
  38              // To obtain the general settings configurations of PowerToys Settings.
  39              ArgumentNullException.ThrowIfNull(settingsRepository);
  40  
  41              GeneralSettingsConfig = settingsRepository.SettingsConfig;
  42  
  43              InitializeEnabledValues();
  44  
  45              // To obtain the find my mouse settings, if the file exists.
  46              // If not, to create a file with the default settings and to return the default configurations.
  47              ArgumentNullException.ThrowIfNull(findMyMouseSettingsRepository);
  48  
  49              FindMyMouseSettingsConfig = findMyMouseSettingsRepository.SettingsConfig;
  50              _findMyMouseActivationMethod = FindMyMouseSettingsConfig.Properties.ActivationMethod.Value < 4 ? FindMyMouseSettingsConfig.Properties.ActivationMethod.Value : 0;
  51              _findMyMouseIncludeWinKey = FindMyMouseSettingsConfig.Properties.IncludeWinKey.Value;
  52              _findMyMouseDoNotActivateOnGameMode = FindMyMouseSettingsConfig.Properties.DoNotActivateOnGameMode.Value;
  53  
  54              string backgroundColor = FindMyMouseSettingsConfig.Properties.BackgroundColor.Value;
  55              _findMyMouseBackgroundColor = !string.IsNullOrEmpty(backgroundColor) ? backgroundColor : "#80000000";
  56  
  57              string spotlightColor = FindMyMouseSettingsConfig.Properties.SpotlightColor.Value;
  58              _findMyMouseSpotlightColor = !string.IsNullOrEmpty(spotlightColor) ? spotlightColor : "#80FFFFFF";
  59  
  60              _findMyMouseSpotlightRadius = FindMyMouseSettingsConfig.Properties.SpotlightRadius.Value;
  61              _findMyMouseAnimationDurationMs = FindMyMouseSettingsConfig.Properties.AnimationDurationMs.Value;
  62              _findMyMouseSpotlightInitialZoom = FindMyMouseSettingsConfig.Properties.SpotlightInitialZoom.Value;
  63              _findMyMouseExcludedApps = FindMyMouseSettingsConfig.Properties.ExcludedApps.Value;
  64              _findMyMouseShakingMinimumDistance = FindMyMouseSettingsConfig.Properties.ShakingMinimumDistance.Value;
  65              _findMyMouseShakingIntervalMs = FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value;
  66              _findMyMouseShakingFactor = FindMyMouseSettingsConfig.Properties.ShakingFactor.Value;
  67  
  68              ArgumentNullException.ThrowIfNull(mouseHighlighterSettingsRepository);
  69  
  70              MouseHighlighterSettingsConfig = mouseHighlighterSettingsRepository.SettingsConfig;
  71              string leftClickColor = MouseHighlighterSettingsConfig.Properties.LeftButtonClickColor.Value;
  72              _highlighterLeftButtonClickColor = !string.IsNullOrEmpty(leftClickColor) ? leftClickColor : "#a6FFFF00";
  73  
  74              string rightClickColor = MouseHighlighterSettingsConfig.Properties.RightButtonClickColor.Value;
  75              _highlighterRightButtonClickColor = !string.IsNullOrEmpty(rightClickColor) ? rightClickColor : "#a60000FF";
  76  
  77              string alwaysColor = MouseHighlighterSettingsConfig.Properties.AlwaysColor.Value;
  78              _highlighterAlwaysColor = !string.IsNullOrEmpty(alwaysColor) ? alwaysColor : "#00FF0000";
  79              _isSpotlightModeEnabled = MouseHighlighterSettingsConfig.Properties.SpotlightMode.Value;
  80  
  81              _highlighterRadius = MouseHighlighterSettingsConfig.Properties.HighlightRadius.Value;
  82              _highlightFadeDelayMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDelayMs.Value;
  83              _highlightFadeDurationMs = MouseHighlighterSettingsConfig.Properties.HighlightFadeDurationMs.Value;
  84              _highlighterAutoActivate = MouseHighlighterSettingsConfig.Properties.AutoActivate.Value;
  85  
  86              this.InitializeMouseJumpSettings(mouseJumpSettingsRepository);
  87  
  88              ArgumentNullException.ThrowIfNull(mousePointerCrosshairsSettingsRepository);
  89  
  90              MousePointerCrosshairsSettingsConfig = mousePointerCrosshairsSettingsRepository.SettingsConfig;
  91  
  92              string crosshairsColor = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsColor.Value;
  93              _mousePointerCrosshairsColor = !string.IsNullOrEmpty(crosshairsColor) ? crosshairsColor : "#FF0000";
  94  
  95              string crosshairsBorderColor = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderColor.Value;
  96              _mousePointerCrosshairsBorderColor = !string.IsNullOrEmpty(crosshairsBorderColor) ? crosshairsBorderColor : "#FFFFFF";
  97  
  98              _mousePointerCrosshairsOpacity = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOpacity.Value;
  99              _mousePointerCrosshairsRadius = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsRadius.Value;
 100              _mousePointerCrosshairsThickness = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value;
 101              _mousePointerCrosshairsBorderSize = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value;
 102              _mousePointerCrosshairsAutoHide = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value;
 103              _mousePointerCrosshairsIsFixedLengthEnabled = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value;
 104              _mousePointerCrosshairsFixedLength = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value;
 105              _mousePointerCrosshairsOrientation = MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value;
 106              _mousePointerCrosshairsAutoActivate = MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value;
 107  
 108              ArgumentNullException.ThrowIfNull(cursorWrapSettingsRepository);
 109  
 110              CursorWrapSettingsConfig = cursorWrapSettingsRepository.SettingsConfig;
 111              _cursorWrapAutoActivate = CursorWrapSettingsConfig.Properties.AutoActivate.Value;
 112  
 113              // Null-safe access in case property wasn't upgraded yet - default to TRUE
 114              _cursorWrapDisableWrapDuringDrag = CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag?.Value ?? true;
 115  
 116              // Null-safe access in case property wasn't upgraded yet - default to 0 (Both)
 117              _cursorWrapWrapMode = CursorWrapSettingsConfig.Properties.WrapMode?.Value ?? 0;
 118  
 119              // Null-safe access in case property wasn't upgraded yet - default to false
 120              _cursorWrapDisableOnSingleMonitor = CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor?.Value ?? false;
 121  
 122              int isEnabled = 0;
 123  
 124              Utilities.NativeMethods.SystemParametersInfo(Utilities.NativeMethods.SPI_GETCLIENTAREAANIMATION, 0, ref isEnabled, 0);
 125              _isAnimationEnabledBySystem = isEnabled != 0;
 126  
 127              // set the callback functions value to handle outgoing IPC message.
 128              SendConfigMSG = ipcMSGCallBackFunc;
 129          }
 130  
 131          private void InitializeEnabledValues()
 132          {
 133              _findMyMouseEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFindMyMouseEnabledValue();
 134              if (_findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
 135              {
 136                  // Get the enabled state from GPO.
 137                  _findMyMouseEnabledStateIsGPOConfigured = true;
 138                  _isFindMyMouseEnabled = _findMyMouseEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
 139              }
 140              else
 141              {
 142                  _isFindMyMouseEnabled = GeneralSettingsConfig.Enabled.FindMyMouse;
 143              }
 144  
 145              _highlighterEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMouseHighlighterEnabledValue();
 146              if (_highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
 147              {
 148                  // Get the enabled state from GPO.
 149                  _highlighterEnabledStateIsGPOConfigured = true;
 150                  _isMouseHighlighterEnabled = _highlighterEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
 151              }
 152              else
 153              {
 154                  _isMouseHighlighterEnabled = GeneralSettingsConfig.Enabled.MouseHighlighter;
 155              }
 156  
 157              this.InitializeMouseJumpEnabledValues();
 158  
 159              _mousePointerCrosshairsEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue();
 160              if (_mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
 161              {
 162                  // Get the enabled state from GPO.
 163                  _mousePointerCrosshairsEnabledStateGPOConfigured = true;
 164                  _isMousePointerCrosshairsEnabled = _mousePointerCrosshairsEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
 165              }
 166              else
 167              {
 168                  _isMousePointerCrosshairsEnabled = GeneralSettingsConfig.Enabled.MousePointerCrosshairs;
 169              }
 170  
 171              _cursorWrapEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredCursorWrapEnabledValue();
 172              if (_cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
 173              {
 174                  // Get the enabled state from GPO.
 175                  _cursorWrapEnabledStateIsGPOConfigured = true;
 176                  _isCursorWrapEnabled = _cursorWrapEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
 177              }
 178              else
 179              {
 180                  _isCursorWrapEnabled = GeneralSettingsConfig.Enabled.CursorWrap;
 181              }
 182          }
 183  
 184          public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings()
 185          {
 186              var hotkeysDict = new Dictionary<string, HotkeySettings[]>
 187              {
 188                  [FindMyMouseSettings.ModuleName] = [FindMyMouseActivationShortcut],
 189                  [MouseHighlighterSettings.ModuleName] = [MouseHighlighterActivationShortcut],
 190                  [MousePointerCrosshairsSettings.ModuleName] = [
 191                      MousePointerCrosshairsActivationShortcut,
 192                      GlidingCursorActivationShortcut],
 193                  [MouseJumpSettings.ModuleName] = [MouseJumpActivationShortcut],
 194                  [CursorWrapSettings.ModuleName] = [CursorWrapActivationShortcut],
 195              };
 196  
 197              return hotkeysDict;
 198          }
 199  
 200          public bool IsFindMyMouseEnabled
 201          {
 202              get => _isFindMyMouseEnabled;
 203              set
 204              {
 205                  if (_findMyMouseEnabledStateIsGPOConfigured)
 206                  {
 207                      // If it's GPO configured, shouldn't be able to change this state.
 208                      return;
 209                  }
 210  
 211                  if (_isFindMyMouseEnabled != value)
 212                  {
 213                      _isFindMyMouseEnabled = value;
 214  
 215                      GeneralSettingsConfig.Enabled.FindMyMouse = value;
 216                      OnPropertyChanged(nameof(IsFindMyMouseEnabled));
 217  
 218                      OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
 219                      SendConfigMSG(outgoing.ToString());
 220  
 221                      NotifyFindMyMousePropertyChanged();
 222                  }
 223              }
 224          }
 225  
 226          public bool IsFindMyMouseEnabledGpoConfigured
 227          {
 228              get => _findMyMouseEnabledStateIsGPOConfigured;
 229          }
 230  
 231          public int FindMyMouseActivationMethod
 232          {
 233              get
 234              {
 235                  return _findMyMouseActivationMethod;
 236              }
 237  
 238              set
 239              {
 240                  if (value != _findMyMouseActivationMethod)
 241                  {
 242                      _findMyMouseActivationMethod = value;
 243                      FindMyMouseSettingsConfig.Properties.ActivationMethod.Value = value;
 244                      NotifyFindMyMousePropertyChanged();
 245                  }
 246              }
 247          }
 248  
 249          public bool FindMyMouseIncludeWinKey
 250          {
 251              get
 252              {
 253                  return _findMyMouseIncludeWinKey;
 254              }
 255  
 256              set
 257              {
 258                  if (_findMyMouseIncludeWinKey != value)
 259                  {
 260                      _findMyMouseIncludeWinKey = value;
 261                      FindMyMouseSettingsConfig.Properties.IncludeWinKey.Value = value;
 262                      NotifyFindMyMousePropertyChanged();
 263                  }
 264              }
 265          }
 266  
 267          public HotkeySettings FindMyMouseActivationShortcut
 268          {
 269              get
 270              {
 271                  return FindMyMouseSettingsConfig.Properties.ActivationShortcut;
 272              }
 273  
 274              set
 275              {
 276                  if (FindMyMouseSettingsConfig.Properties.ActivationShortcut != value)
 277                  {
 278                      FindMyMouseSettingsConfig.Properties.ActivationShortcut = value ?? FindMyMouseSettingsConfig.Properties.DefaultActivationShortcut;
 279                      NotifyFindMyMousePropertyChanged();
 280                  }
 281              }
 282          }
 283  
 284          public bool FindMyMouseDoNotActivateOnGameMode
 285          {
 286              get
 287              {
 288                  return _findMyMouseDoNotActivateOnGameMode;
 289              }
 290  
 291              set
 292              {
 293                  if (_findMyMouseDoNotActivateOnGameMode != value)
 294                  {
 295                      _findMyMouseDoNotActivateOnGameMode = value;
 296                      FindMyMouseSettingsConfig.Properties.DoNotActivateOnGameMode.Value = value;
 297                      NotifyFindMyMousePropertyChanged();
 298                  }
 299              }
 300          }
 301  
 302          public string FindMyMouseBackgroundColor
 303          {
 304              get
 305              {
 306                  return _findMyMouseBackgroundColor;
 307              }
 308  
 309              set
 310              {
 311                  value = (value != null) ? SettingsUtilities.ToARGBHex(value) : "#FF000000";
 312                  if (!value.Equals(_findMyMouseBackgroundColor, StringComparison.OrdinalIgnoreCase))
 313                  {
 314                      _findMyMouseBackgroundColor = value;
 315                      FindMyMouseSettingsConfig.Properties.BackgroundColor.Value = value;
 316                      NotifyFindMyMousePropertyChanged();
 317                  }
 318              }
 319          }
 320  
 321          public string FindMyMouseSpotlightColor
 322          {
 323              get
 324              {
 325                  return _findMyMouseSpotlightColor;
 326              }
 327  
 328              set
 329              {
 330                  value = (value != null) ? SettingsUtilities.ToARGBHex(value) : "#FFFFFFFF";
 331                  if (!value.Equals(_findMyMouseSpotlightColor, StringComparison.OrdinalIgnoreCase))
 332                  {
 333                      _findMyMouseSpotlightColor = value;
 334                      FindMyMouseSettingsConfig.Properties.SpotlightColor.Value = value;
 335                      NotifyFindMyMousePropertyChanged();
 336                  }
 337              }
 338          }
 339  
 340          public int FindMyMouseSpotlightRadius
 341          {
 342              get
 343              {
 344                  return _findMyMouseSpotlightRadius;
 345              }
 346  
 347              set
 348              {
 349                  if (value != _findMyMouseSpotlightRadius)
 350                  {
 351                      _findMyMouseSpotlightRadius = value;
 352                      FindMyMouseSettingsConfig.Properties.SpotlightRadius.Value = value;
 353                      NotifyFindMyMousePropertyChanged();
 354                  }
 355              }
 356          }
 357  
 358          public bool IsAnimationEnabledBySystem
 359          {
 360              get
 361              {
 362                  return _isAnimationEnabledBySystem;
 363              }
 364  
 365              set
 366              {
 367                  _isAnimationEnabledBySystem = value;
 368              }
 369          }
 370  
 371          public int FindMyMouseAnimationDurationMs
 372          {
 373              get
 374              {
 375                  return _findMyMouseAnimationDurationMs;
 376              }
 377  
 378              set
 379              {
 380                  if (value != _findMyMouseAnimationDurationMs)
 381                  {
 382                      _findMyMouseAnimationDurationMs = value;
 383                      FindMyMouseSettingsConfig.Properties.AnimationDurationMs.Value = value;
 384                      NotifyFindMyMousePropertyChanged();
 385                  }
 386              }
 387          }
 388  
 389          public int FindMyMouseSpotlightInitialZoom
 390          {
 391              get
 392              {
 393                  return _findMyMouseSpotlightInitialZoom;
 394              }
 395  
 396              set
 397              {
 398                  if (value != _findMyMouseSpotlightInitialZoom)
 399                  {
 400                      _findMyMouseSpotlightInitialZoom = value;
 401                      FindMyMouseSettingsConfig.Properties.SpotlightInitialZoom.Value = value;
 402                      NotifyFindMyMousePropertyChanged();
 403                  }
 404              }
 405          }
 406  
 407          public string FindMyMouseExcludedApps
 408          {
 409              get
 410              {
 411                  return _findMyMouseExcludedApps;
 412              }
 413  
 414              set
 415              {
 416                  if (value != _findMyMouseExcludedApps)
 417                  {
 418                      _findMyMouseExcludedApps = value;
 419                      FindMyMouseSettingsConfig.Properties.ExcludedApps.Value = value;
 420                      NotifyFindMyMousePropertyChanged();
 421                  }
 422              }
 423          }
 424  
 425          public int FindMyMouseShakingMinimumDistance
 426          {
 427              get
 428              {
 429                  return _findMyMouseShakingMinimumDistance;
 430              }
 431  
 432              set
 433              {
 434                  if (value != _findMyMouseShakingMinimumDistance)
 435                  {
 436                      _findMyMouseShakingMinimumDistance = value;
 437                      FindMyMouseSettingsConfig.Properties.ShakingMinimumDistance.Value = value;
 438                      NotifyFindMyMousePropertyChanged();
 439                  }
 440              }
 441          }
 442  
 443          public int FindMyMouseShakingIntervalMs
 444          {
 445              get
 446              {
 447                  return _findMyMouseShakingIntervalMs;
 448              }
 449  
 450              set
 451              {
 452                  if (value != _findMyMouseShakingIntervalMs)
 453                  {
 454                      _findMyMouseShakingIntervalMs = value;
 455                      FindMyMouseSettingsConfig.Properties.ShakingIntervalMs.Value = value;
 456                      NotifyFindMyMousePropertyChanged();
 457                  }
 458              }
 459          }
 460  
 461          public int FindMyMouseShakingFactor
 462          {
 463              get
 464              {
 465                  return _findMyMouseShakingFactor;
 466              }
 467  
 468              set
 469              {
 470                  if (value != _findMyMouseShakingFactor)
 471                  {
 472                      _findMyMouseShakingFactor = value;
 473                      FindMyMouseSettingsConfig.Properties.ShakingFactor.Value = value;
 474                      NotifyFindMyMousePropertyChanged();
 475                  }
 476              }
 477          }
 478  
 479          public void NotifyFindMyMousePropertyChanged([CallerMemberName] string propertyName = null)
 480          {
 481              OnPropertyChanged(propertyName);
 482  
 483              SndFindMyMouseSettings outsettings = new SndFindMyMouseSettings(FindMyMouseSettingsConfig);
 484              SndModuleSettings<SndFindMyMouseSettings> ipcMessage = new SndModuleSettings<SndFindMyMouseSettings>(outsettings);
 485              SendConfigMSG(ipcMessage.ToJsonString());
 486              SettingsUtils.SaveSettings(FindMyMouseSettingsConfig.ToJsonString(), FindMyMouseSettings.ModuleName);
 487          }
 488  
 489          public bool IsMouseHighlighterEnabled
 490          {
 491              get => _isMouseHighlighterEnabled;
 492              set
 493              {
 494                  if (_highlighterEnabledStateIsGPOConfigured)
 495                  {
 496                      // If it's GPO configured, shouldn't be able to change this state.
 497                      return;
 498                  }
 499  
 500                  if (_isMouseHighlighterEnabled != value)
 501                  {
 502                      _isMouseHighlighterEnabled = value;
 503  
 504                      GeneralSettingsConfig.Enabled.MouseHighlighter = value;
 505                      OnPropertyChanged(nameof(_isMouseHighlighterEnabled));
 506  
 507                      OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
 508                      SendConfigMSG(outgoing.ToString());
 509  
 510                      NotifyMouseHighlighterPropertyChanged();
 511                  }
 512              }
 513          }
 514  
 515          public bool IsHighlighterEnabledGpoConfigured
 516          {
 517              get => _highlighterEnabledStateIsGPOConfigured;
 518          }
 519  
 520          public HotkeySettings MouseHighlighterActivationShortcut
 521          {
 522              get
 523              {
 524                  return MouseHighlighterSettingsConfig.Properties.ActivationShortcut;
 525              }
 526  
 527              set
 528              {
 529                  if (MouseHighlighterSettingsConfig.Properties.ActivationShortcut != value)
 530                  {
 531                      MouseHighlighterSettingsConfig.Properties.ActivationShortcut = value ?? MouseHighlighterSettingsConfig.Properties.DefaultActivationShortcut;
 532                      NotifyMouseHighlighterPropertyChanged();
 533                  }
 534              }
 535          }
 536  
 537          public string MouseHighlighterLeftButtonClickColor
 538          {
 539              get
 540              {
 541                  return _highlighterLeftButtonClickColor;
 542              }
 543  
 544              set
 545              {
 546                  value = SettingsUtilities.ToARGBHex(value);
 547                  if (!value.Equals(_highlighterLeftButtonClickColor, StringComparison.OrdinalIgnoreCase))
 548                  {
 549                      _highlighterLeftButtonClickColor = value;
 550                      MouseHighlighterSettingsConfig.Properties.LeftButtonClickColor.Value = value;
 551                      NotifyMouseHighlighterPropertyChanged();
 552                  }
 553              }
 554          }
 555  
 556          public string MouseHighlighterRightButtonClickColor
 557          {
 558              get
 559              {
 560                  return _highlighterRightButtonClickColor;
 561              }
 562  
 563              set
 564              {
 565                  value = SettingsUtilities.ToARGBHex(value);
 566                  if (!value.Equals(_highlighterRightButtonClickColor, StringComparison.OrdinalIgnoreCase))
 567                  {
 568                      _highlighterRightButtonClickColor = value;
 569                      MouseHighlighterSettingsConfig.Properties.RightButtonClickColor.Value = value;
 570                      NotifyMouseHighlighterPropertyChanged();
 571                  }
 572              }
 573          }
 574  
 575          public string MouseHighlighterAlwaysColor
 576          {
 577              get
 578              {
 579                  return _highlighterAlwaysColor;
 580              }
 581  
 582              set
 583              {
 584                  value = SettingsUtilities.ToARGBHex(value);
 585                  if (!value.Equals(_highlighterAlwaysColor, StringComparison.OrdinalIgnoreCase))
 586                  {
 587                      _highlighterAlwaysColor = value;
 588                      MouseHighlighterSettingsConfig.Properties.AlwaysColor.Value = value;
 589                      NotifyMouseHighlighterPropertyChanged();
 590                  }
 591              }
 592          }
 593  
 594          public bool IsSpotlightModeEnabled
 595          {
 596              get => _isSpotlightModeEnabled;
 597              set
 598              {
 599                  if (_isSpotlightModeEnabled != value)
 600                  {
 601                      _isSpotlightModeEnabled = value;
 602                      MouseHighlighterSettingsConfig.Properties.SpotlightMode.Value = value;
 603                      NotifyMouseHighlighterPropertyChanged();
 604                  }
 605              }
 606          }
 607  
 608          public int MouseHighlighterRadius
 609          {
 610              get
 611              {
 612                  return _highlighterRadius;
 613              }
 614  
 615              set
 616              {
 617                  if (value != _highlighterRadius)
 618                  {
 619                      _highlighterRadius = value;
 620                      MouseHighlighterSettingsConfig.Properties.HighlightRadius.Value = value;
 621                      NotifyMouseHighlighterPropertyChanged();
 622                  }
 623              }
 624          }
 625  
 626          public int MouseHighlighterFadeDelayMs
 627          {
 628              get
 629              {
 630                  return _highlightFadeDelayMs;
 631              }
 632  
 633              set
 634              {
 635                  if (value != _highlightFadeDelayMs)
 636                  {
 637                      _highlightFadeDelayMs = value;
 638                      MouseHighlighterSettingsConfig.Properties.HighlightFadeDelayMs.Value = value;
 639                      NotifyMouseHighlighterPropertyChanged();
 640                  }
 641              }
 642          }
 643  
 644          public int MouseHighlighterFadeDurationMs
 645          {
 646              get
 647              {
 648                  return _highlightFadeDurationMs;
 649              }
 650  
 651              set
 652              {
 653                  if (value != _highlightFadeDurationMs)
 654                  {
 655                      _highlightFadeDurationMs = value;
 656                      MouseHighlighterSettingsConfig.Properties.HighlightFadeDurationMs.Value = value;
 657                      NotifyMouseHighlighterPropertyChanged();
 658                  }
 659              }
 660          }
 661  
 662          public bool MouseHighlighterAutoActivate
 663          {
 664              get
 665              {
 666                  return _highlighterAutoActivate;
 667              }
 668  
 669              set
 670              {
 671                  if (value != _highlighterAutoActivate)
 672                  {
 673                      _highlighterAutoActivate = value;
 674                      MouseHighlighterSettingsConfig.Properties.AutoActivate.Value = value;
 675                      NotifyMouseHighlighterPropertyChanged();
 676                  }
 677              }
 678          }
 679  
 680          public void NotifyMouseHighlighterPropertyChanged([CallerMemberName] string propertyName = null)
 681          {
 682              OnPropertyChanged(propertyName);
 683  
 684              SndMouseHighlighterSettings outsettings = new SndMouseHighlighterSettings(MouseHighlighterSettingsConfig);
 685              SndModuleSettings<SndMouseHighlighterSettings> ipcMessage = new SndModuleSettings<SndMouseHighlighterSettings>(outsettings);
 686              SendConfigMSG(ipcMessage.ToJsonString());
 687              SettingsUtils.SaveSettings(MouseHighlighterSettingsConfig.ToJsonString(), MouseHighlighterSettings.ModuleName);
 688          }
 689  
 690          public bool IsMousePointerCrosshairsEnabled
 691          {
 692              get => _isMousePointerCrosshairsEnabled;
 693              set
 694              {
 695                  if (_mousePointerCrosshairsEnabledStateGPOConfigured)
 696                  {
 697                      // If it's GPO configured, shouldn't be able to change this state.
 698                      return;
 699                  }
 700  
 701                  if (_isMousePointerCrosshairsEnabled != value)
 702                  {
 703                      _isMousePointerCrosshairsEnabled = value;
 704  
 705                      GeneralSettingsConfig.Enabled.MousePointerCrosshairs = value;
 706                      OnPropertyChanged(nameof(_isMousePointerCrosshairsEnabled));
 707  
 708                      OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
 709                      SendConfigMSG(outgoing.ToString());
 710  
 711                      NotifyMousePointerCrosshairsPropertyChanged();
 712                  }
 713              }
 714          }
 715  
 716          public bool IsMousePointerCrosshairsEnabledGpoConfigured
 717          {
 718              get => _mousePointerCrosshairsEnabledStateGPOConfigured;
 719          }
 720  
 721          public HotkeySettings MousePointerCrosshairsActivationShortcut
 722          {
 723              get
 724              {
 725                  return MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut;
 726              }
 727  
 728              set
 729              {
 730                  if (MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut != value)
 731                  {
 732                      MousePointerCrosshairsSettingsConfig.Properties.ActivationShortcut = value ?? MousePointerCrosshairsSettingsConfig.Properties.DefaultActivationShortcut;
 733                      NotifyMousePointerCrosshairsPropertyChanged();
 734                  }
 735              }
 736          }
 737  
 738          public string MousePointerCrosshairsColor
 739          {
 740              get
 741              {
 742                  return _mousePointerCrosshairsColor;
 743              }
 744  
 745              set
 746              {
 747                  value = SettingsUtilities.ToRGBHex(value);
 748                  if (!value.Equals(_mousePointerCrosshairsColor, StringComparison.OrdinalIgnoreCase))
 749                  {
 750                      _mousePointerCrosshairsColor = value;
 751                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsColor.Value = value;
 752                      NotifyMousePointerCrosshairsPropertyChanged();
 753                  }
 754              }
 755          }
 756  
 757          public int MousePointerCrosshairsOpacity
 758          {
 759              get
 760              {
 761                  return _mousePointerCrosshairsOpacity;
 762              }
 763  
 764              set
 765              {
 766                  if (value != _mousePointerCrosshairsOpacity)
 767                  {
 768                      _mousePointerCrosshairsOpacity = value;
 769                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOpacity.Value = value;
 770                      NotifyMousePointerCrosshairsPropertyChanged();
 771                  }
 772              }
 773          }
 774  
 775          public int MousePointerCrosshairsRadius
 776          {
 777              get
 778              {
 779                  return _mousePointerCrosshairsRadius;
 780              }
 781  
 782              set
 783              {
 784                  if (value != _mousePointerCrosshairsRadius)
 785                  {
 786                      _mousePointerCrosshairsRadius = value;
 787                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsRadius.Value = value;
 788                      NotifyMousePointerCrosshairsPropertyChanged();
 789                  }
 790              }
 791          }
 792  
 793          public int MousePointerCrosshairsThickness
 794          {
 795              get
 796              {
 797                  return _mousePointerCrosshairsThickness;
 798              }
 799  
 800              set
 801              {
 802                  if (value != _mousePointerCrosshairsThickness)
 803                  {
 804                      _mousePointerCrosshairsThickness = value;
 805                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsThickness.Value = value;
 806                      NotifyMousePointerCrosshairsPropertyChanged();
 807                  }
 808              }
 809          }
 810  
 811          public string MousePointerCrosshairsBorderColor
 812          {
 813              get
 814              {
 815                  return _mousePointerCrosshairsBorderColor;
 816              }
 817  
 818              set
 819              {
 820                  value = SettingsUtilities.ToRGBHex(value);
 821                  if (!value.Equals(_mousePointerCrosshairsBorderColor, StringComparison.OrdinalIgnoreCase))
 822                  {
 823                      _mousePointerCrosshairsBorderColor = value;
 824                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderColor.Value = value;
 825                      NotifyMousePointerCrosshairsPropertyChanged();
 826                  }
 827              }
 828          }
 829  
 830          public int MousePointerCrosshairsBorderSize
 831          {
 832              get
 833              {
 834                  return _mousePointerCrosshairsBorderSize;
 835              }
 836  
 837              set
 838              {
 839                  if (value != _mousePointerCrosshairsBorderSize)
 840                  {
 841                      _mousePointerCrosshairsBorderSize = value;
 842                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsBorderSize.Value = value;
 843                      NotifyMousePointerCrosshairsPropertyChanged();
 844                  }
 845              }
 846          }
 847  
 848          public bool MousePointerCrosshairsAutoHide
 849          {
 850              get
 851              {
 852                  return _mousePointerCrosshairsAutoHide;
 853              }
 854  
 855              set
 856              {
 857                  if (value != _mousePointerCrosshairsAutoHide)
 858                  {
 859                      _mousePointerCrosshairsAutoHide = value;
 860                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsAutoHide.Value = value;
 861                      NotifyMousePointerCrosshairsPropertyChanged();
 862                  }
 863              }
 864          }
 865  
 866          public bool MousePointerCrosshairsIsFixedLengthEnabled
 867          {
 868              get
 869              {
 870                  return _mousePointerCrosshairsIsFixedLengthEnabled;
 871              }
 872  
 873              set
 874              {
 875                  if (value != _mousePointerCrosshairsIsFixedLengthEnabled)
 876                  {
 877                      _mousePointerCrosshairsIsFixedLengthEnabled = value;
 878                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsIsFixedLengthEnabled.Value = value;
 879                      NotifyMousePointerCrosshairsPropertyChanged();
 880                  }
 881              }
 882          }
 883  
 884          public int MousePointerCrosshairsFixedLength
 885          {
 886              get
 887              {
 888                  return _mousePointerCrosshairsFixedLength;
 889              }
 890  
 891              set
 892              {
 893                  if (value != _mousePointerCrosshairsFixedLength)
 894                  {
 895                      _mousePointerCrosshairsFixedLength = value;
 896                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsFixedLength.Value = value;
 897                      NotifyMousePointerCrosshairsPropertyChanged();
 898                  }
 899              }
 900          }
 901  
 902          public int MousePointerCrosshairsOrientation
 903          {
 904              get
 905              {
 906                  return _mousePointerCrosshairsOrientation;
 907              }
 908  
 909              set
 910              {
 911                  if (value != _mousePointerCrosshairsOrientation)
 912                  {
 913                      _mousePointerCrosshairsOrientation = value;
 914                      MousePointerCrosshairsSettingsConfig.Properties.CrosshairsOrientation.Value = value;
 915                      NotifyMousePointerCrosshairsPropertyChanged();
 916                  }
 917              }
 918          }
 919  
 920          public bool MousePointerCrosshairsAutoActivate
 921          {
 922              get
 923              {
 924                  return _mousePointerCrosshairsAutoActivate;
 925              }
 926  
 927              set
 928              {
 929                  if (value != _mousePointerCrosshairsAutoActivate)
 930                  {
 931                      _mousePointerCrosshairsAutoActivate = value;
 932                      MousePointerCrosshairsSettingsConfig.Properties.AutoActivate.Value = value;
 933                      NotifyMousePointerCrosshairsPropertyChanged();
 934                  }
 935              }
 936          }
 937  
 938          public int GlidingCursorTravelSpeed
 939          {
 940              get => MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value;
 941              set
 942              {
 943                  if (MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value != value)
 944                  {
 945                      MousePointerCrosshairsSettingsConfig.Properties.GlidingTravelSpeed.Value = value;
 946                      NotifyMousePointerCrosshairsPropertyChanged();
 947                  }
 948              }
 949          }
 950  
 951          public int GlidingCursorDelaySpeed
 952          {
 953              get => MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value;
 954              set
 955              {
 956                  if (MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value != value)
 957                  {
 958                      MousePointerCrosshairsSettingsConfig.Properties.GlidingDelaySpeed.Value = value;
 959                      NotifyMousePointerCrosshairsPropertyChanged();
 960                  }
 961              }
 962          }
 963  
 964          public HotkeySettings GlidingCursorActivationShortcut
 965          {
 966              get
 967              {
 968                  return MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut;
 969              }
 970  
 971              set
 972              {
 973                  if (MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut != value)
 974                  {
 975                      MousePointerCrosshairsSettingsConfig.Properties.GlidingCursorActivationShortcut = value ?? MousePointerCrosshairsSettingsConfig.Properties.DefaultGlidingCursorActivationShortcut;
 976                      NotifyMousePointerCrosshairsPropertyChanged();
 977                  }
 978              }
 979          }
 980  
 981          public void NotifyMousePointerCrosshairsPropertyChanged([CallerMemberName] string propertyName = null)
 982          {
 983              OnPropertyChanged(propertyName);
 984  
 985              SndMousePointerCrosshairsSettings outsettings = new SndMousePointerCrosshairsSettings(MousePointerCrosshairsSettingsConfig);
 986              SndModuleSettings<SndMousePointerCrosshairsSettings> ipcMessage = new SndModuleSettings<SndMousePointerCrosshairsSettings>(outsettings);
 987              SendConfigMSG(ipcMessage.ToJsonString());
 988              SettingsUtils.SaveSettings(MousePointerCrosshairsSettingsConfig.ToJsonString(), MousePointerCrosshairsSettings.ModuleName);
 989          }
 990  
 991          public bool IsCursorWrapEnabled
 992          {
 993              get => _isCursorWrapEnabled;
 994              set
 995              {
 996                  if (_cursorWrapEnabledStateIsGPOConfigured)
 997                  {
 998                      // If it's GPO configured, shouldn't be able to change this state.
 999                      return;
1000                  }
1001  
1002                  if (_isCursorWrapEnabled != value)
1003                  {
1004                      _isCursorWrapEnabled = value;
1005  
1006                      GeneralSettingsConfig.Enabled.CursorWrap = value;
1007                      OnPropertyChanged(nameof(IsCursorWrapEnabled));
1008  
1009                      OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
1010                      SendConfigMSG(outgoing.ToString());
1011  
1012                      NotifyCursorWrapPropertyChanged();
1013                  }
1014              }
1015          }
1016  
1017          public bool IsCursorWrapEnabledGpoConfigured
1018          {
1019              get => _cursorWrapEnabledStateIsGPOConfigured;
1020          }
1021  
1022          public HotkeySettings CursorWrapActivationShortcut
1023          {
1024              get
1025              {
1026                  return CursorWrapSettingsConfig.Properties.ActivationShortcut;
1027              }
1028  
1029              set
1030              {
1031                  if (CursorWrapSettingsConfig.Properties.ActivationShortcut != value)
1032                  {
1033                      CursorWrapSettingsConfig.Properties.ActivationShortcut = value ?? CursorWrapSettingsConfig.Properties.DefaultActivationShortcut;
1034                      NotifyCursorWrapPropertyChanged();
1035                  }
1036              }
1037          }
1038  
1039          public bool CursorWrapAutoActivate
1040          {
1041              get
1042              {
1043                  return _cursorWrapAutoActivate;
1044              }
1045  
1046              set
1047              {
1048                  if (value != _cursorWrapAutoActivate)
1049                  {
1050                      _cursorWrapAutoActivate = value;
1051                      CursorWrapSettingsConfig.Properties.AutoActivate.Value = value;
1052                      NotifyCursorWrapPropertyChanged();
1053                  }
1054              }
1055          }
1056  
1057          public bool CursorWrapDisableWrapDuringDrag
1058          {
1059              get
1060              {
1061                  return _cursorWrapDisableWrapDuringDrag;
1062              }
1063  
1064              set
1065              {
1066                  if (value != _cursorWrapDisableWrapDuringDrag)
1067                  {
1068                      _cursorWrapDisableWrapDuringDrag = value;
1069  
1070                      // Ensure the property exists before setting value
1071                      if (CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag == null)
1072                      {
1073                          CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag = new BoolProperty(value);
1074                      }
1075                      else
1076                      {
1077                          CursorWrapSettingsConfig.Properties.DisableWrapDuringDrag.Value = value;
1078                      }
1079  
1080                      NotifyCursorWrapPropertyChanged();
1081                  }
1082              }
1083          }
1084  
1085          public int CursorWrapWrapMode
1086          {
1087              get
1088              {
1089                  return _cursorWrapWrapMode;
1090              }
1091  
1092              set
1093              {
1094                  if (value != _cursorWrapWrapMode)
1095                  {
1096                      _cursorWrapWrapMode = value;
1097  
1098                      // Ensure the property exists before setting value
1099                      if (CursorWrapSettingsConfig.Properties.WrapMode == null)
1100                      {
1101                          CursorWrapSettingsConfig.Properties.WrapMode = new IntProperty(value);
1102                      }
1103                      else
1104                      {
1105                          CursorWrapSettingsConfig.Properties.WrapMode.Value = value;
1106                      }
1107  
1108                      NotifyCursorWrapPropertyChanged();
1109                  }
1110              }
1111          }
1112  
1113          public bool CursorWrapDisableOnSingleMonitor
1114          {
1115              get
1116              {
1117                  return _cursorWrapDisableOnSingleMonitor;
1118              }
1119  
1120              set
1121              {
1122                  if (value != _cursorWrapDisableOnSingleMonitor)
1123                  {
1124                      _cursorWrapDisableOnSingleMonitor = value;
1125  
1126                      // Ensure the property exists before setting value
1127                      if (CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor == null)
1128                      {
1129                          CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor = new BoolProperty(value);
1130                      }
1131                      else
1132                      {
1133                          CursorWrapSettingsConfig.Properties.DisableCursorWrapOnSingleMonitor.Value = value;
1134                      }
1135  
1136                      NotifyCursorWrapPropertyChanged();
1137                  }
1138              }
1139          }
1140  
1141          public void NotifyCursorWrapPropertyChanged([CallerMemberName] string propertyName = null)
1142          {
1143              OnPropertyChanged(propertyName);
1144  
1145              SndCursorWrapSettings outsettings = new SndCursorWrapSettings(CursorWrapSettingsConfig);
1146              SndModuleSettings<SndCursorWrapSettings> ipcMessage = new SndModuleSettings<SndCursorWrapSettings>(outsettings);
1147              SendConfigMSG(ipcMessage.ToJsonString());
1148              SettingsUtils.SaveSettings(CursorWrapSettingsConfig.ToJsonString(), CursorWrapSettings.ModuleName);
1149          }
1150  
1151          public void RefreshEnabledState()
1152          {
1153              InitializeEnabledValues();
1154              OnPropertyChanged(nameof(IsFindMyMouseEnabled));
1155              OnPropertyChanged(nameof(IsMouseHighlighterEnabled));
1156              OnPropertyChanged(nameof(IsMouseJumpEnabled));
1157              OnPropertyChanged(nameof(IsMousePointerCrosshairsEnabled));
1158              OnPropertyChanged(nameof(IsCursorWrapEnabled));
1159          }
1160  
1161          private Func<string, int> SendConfigMSG { get; }
1162  
1163          private GpoRuleConfigured _findMyMouseEnabledGpoRuleConfiguration;
1164          private bool _findMyMouseEnabledStateIsGPOConfigured;
1165          private bool _isFindMyMouseEnabled;
1166          private int _findMyMouseActivationMethod;
1167          private bool _findMyMouseIncludeWinKey;
1168          private bool _findMyMouseDoNotActivateOnGameMode;
1169          private string _findMyMouseBackgroundColor;
1170          private string _findMyMouseSpotlightColor;
1171          private int _findMyMouseSpotlightRadius;
1172          private int _findMyMouseAnimationDurationMs;
1173          private int _findMyMouseSpotlightInitialZoom;
1174          private string _findMyMouseExcludedApps;
1175          private int _findMyMouseShakingMinimumDistance;
1176          private int _findMyMouseShakingIntervalMs;
1177          private int _findMyMouseShakingFactor;
1178  
1179          private GpoRuleConfigured _highlighterEnabledGpoRuleConfiguration;
1180          private bool _highlighterEnabledStateIsGPOConfigured;
1181          private bool _isMouseHighlighterEnabled;
1182          private string _highlighterLeftButtonClickColor;
1183          private string _highlighterRightButtonClickColor;
1184          private string _highlighterAlwaysColor;
1185          private bool _isSpotlightModeEnabled;
1186          private int _highlighterRadius;
1187          private int _highlightFadeDelayMs;
1188          private int _highlightFadeDurationMs;
1189          private bool _highlighterAutoActivate;
1190  
1191          private GpoRuleConfigured _mousePointerCrosshairsEnabledGpoRuleConfiguration;
1192          private bool _mousePointerCrosshairsEnabledStateGPOConfigured;
1193          private bool _isMousePointerCrosshairsEnabled;
1194          private string _mousePointerCrosshairsColor;
1195          private int _mousePointerCrosshairsOpacity;
1196          private int _mousePointerCrosshairsRadius;
1197          private int _mousePointerCrosshairsThickness;
1198          private string _mousePointerCrosshairsBorderColor;
1199          private int _mousePointerCrosshairsBorderSize;
1200          private bool _mousePointerCrosshairsAutoHide;
1201          private bool _mousePointerCrosshairsIsFixedLengthEnabled;
1202          private int _mousePointerCrosshairsFixedLength;
1203          private int _mousePointerCrosshairsOrientation;
1204          private bool _mousePointerCrosshairsAutoActivate;
1205          private bool _isAnimationEnabledBySystem;
1206  
1207          private GpoRuleConfigured _cursorWrapEnabledGpoRuleConfiguration;
1208          private bool _cursorWrapEnabledStateIsGPOConfigured;
1209          private bool _isCursorWrapEnabled;
1210          private bool _cursorWrapAutoActivate;
1211          private bool _cursorWrapDisableWrapDuringDrag; // Will be initialized in constructor from settings
1212          private int _cursorWrapWrapMode; // 0=Both, 1=VerticalOnly, 2=HorizontalOnly
1213          private bool _cursorWrapDisableOnSingleMonitor; // Disable cursor wrap when only one monitor is connected
1214      }
1215  }