FancyZonesViewModel.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.Runtime.CompilerServices; 8 using global::PowerToys.GPOWrapper; 9 using ManagedCommon; 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.UI.Library.ViewModels.Commands; 15 16 namespace Microsoft.PowerToys.Settings.UI.ViewModels 17 { 18 public partial class FancyZonesViewModel : PageViewModelBase 19 { 20 protected override string ModuleName => FancyZonesSettings.ModuleName; 21 22 private SettingsUtils SettingsUtils { get; set; } 23 24 private GeneralSettings GeneralSettingsConfig { get; set; } 25 26 public ButtonClickCommand LaunchEditorEventHandler { get; set; } 27 28 private FancyZonesSettings Settings { get; set; } 29 30 private Func<string, int> SendConfigMSG { get; } 31 32 private string settingsConfigFileFolder = string.Empty; 33 34 private bool _windows11; 35 36 private enum MoveWindowBehaviour 37 { 38 MoveWindowBasedOnZoneIndex = 0, 39 MoveWindowBasedOnPosition, 40 } 41 42 private enum OverlappingZonesAlgorithm 43 { 44 Smallest = 0, 45 Largest = 1, 46 Positional = 2, 47 } 48 49 public FancyZonesViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FancyZonesSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "") 50 { 51 ArgumentNullException.ThrowIfNull(settingsUtils); 52 53 SettingsUtils = settingsUtils; 54 55 // To obtain the general settings configurations of PowerToys Settings. 56 ArgumentNullException.ThrowIfNull(settingsRepository); 57 58 GeneralSettingsConfig = settingsRepository.SettingsConfig; 59 settingsConfigFileFolder = configFileSubfolder; 60 61 // To obtain the settings configurations of Fancy zones. 62 ArgumentNullException.ThrowIfNull(moduleSettingsRepository); 63 64 Settings = moduleSettingsRepository.SettingsConfig; 65 66 LaunchEditorEventHandler = new ButtonClickCommand(LaunchEditor); 67 68 _shiftDrag = Settings.Properties.FancyzonesShiftDrag.Value; 69 _mouseSwitch = Settings.Properties.FancyzonesMouseSwitch.Value; 70 _mouseMiddleButtonSpanningMultipleZones = Settings.Properties.FancyzonesMouseMiddleClickSpanningMultipleZones.Value; 71 _overrideSnapHotkeys = Settings.Properties.FancyzonesOverrideSnapHotkeys.Value; 72 _moveWindowsAcrossMonitors = Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value; 73 _moveWindowBehaviour = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value ? MoveWindowBehaviour.MoveWindowBasedOnPosition : MoveWindowBehaviour.MoveWindowBasedOnZoneIndex; 74 _overlappingZonesAlgorithm = (OverlappingZonesAlgorithm)Settings.Properties.FancyzonesOverlappingZonesAlgorithm.Value; 75 _displayOrWorkAreaChangeMoveWindows = Settings.Properties.FancyzonesDisplayOrWorkAreaChangeMoveWindows.Value; 76 _zoneSetChangeMoveWindows = Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value; 77 _appLastZoneMoveWindows = Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value; 78 _openWindowOnActiveMonitor = Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value; 79 _restoreSize = Settings.Properties.FancyzonesRestoreSize.Value; 80 _quickLayoutSwitch = Settings.Properties.FancyzonesQuickLayoutSwitch.Value; 81 _flashZonesOnQuickLayoutSwitch = Settings.Properties.FancyzonesFlashZonesOnQuickSwitch.Value; 82 _useCursorPosEditorStartupScreen = Settings.Properties.UseCursorposEditorStartupscreen.Value; 83 _showOnAllMonitors = Settings.Properties.FancyzonesShowOnAllMonitors.Value; 84 _spanZonesAcrossMonitors = Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value; 85 _makeDraggedWindowTransparent = Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value; 86 _allowPopupWindowSnap = Settings.Properties.FancyzonesAllowPopupWindowSnap.Value; 87 _allowChildWindowSnap = Settings.Properties.FancyzonesAllowChildWindowSnap.Value; 88 _disableRoundCornersOnSnap = Settings.Properties.FancyzonesDisableRoundCornersOnSnap.Value; 89 _highlightOpacity = Settings.Properties.FancyzonesHighlightOpacity.Value; 90 _excludedApps = Settings.Properties.FancyzonesExcludedApps.Value; 91 _systemTheme = Settings.Properties.FancyzonesSystemTheme.Value; 92 _showZoneNumber = Settings.Properties.FancyzonesShowZoneNumber.Value; 93 _windowSwitching = Settings.Properties.FancyzonesWindowSwitching.Value; 94 95 EditorHotkey = Settings.Properties.FancyzonesEditorHotkey.Value; 96 NextTabHotkey = Settings.Properties.FancyzonesNextTabHotkey.Value; 97 PrevTabHotkey = Settings.Properties.FancyzonesPrevTabHotkey.Value; 98 99 // set the callback functions value to handle outgoing IPC message. 100 SendConfigMSG = ipcMSGCallBackFunc; 101 102 string inactiveColor = Settings.Properties.FancyzonesInActiveColor.Value; 103 _zoneInActiveColor = !string.IsNullOrEmpty(inactiveColor) ? inactiveColor : ConfigDefaults.DefaultFancyZonesInActiveColor; 104 105 string borderColor = Settings.Properties.FancyzonesBorderColor.Value; 106 _zoneBorderColor = !string.IsNullOrEmpty(borderColor) ? borderColor : ConfigDefaults.DefaultFancyzonesBorderColor; 107 108 string highlightColor = Settings.Properties.FancyzonesZoneHighlightColor.Value; 109 _zoneHighlightColor = !string.IsNullOrEmpty(highlightColor) ? highlightColor : ConfigDefaults.DefaultFancyZonesZoneHighlightColor; 110 111 string numberColor = Settings.Properties.FancyzonesNumberColor.Value; 112 _zoneNumberColor = !string.IsNullOrEmpty(numberColor) ? numberColor : ConfigDefaults.DefaultFancyzonesNumberColor; 113 114 InitializeEnabledValue(); 115 116 _windows11 = OSVersionHelper.IsWindows11(); 117 118 // Disable setting on windows 10 119 if (!_windows11 && DisableRoundCornersOnWindowSnap) 120 { 121 DisableRoundCornersOnWindowSnap = false; 122 } 123 } 124 125 private void InitializeEnabledValue() 126 { 127 _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredFancyZonesEnabledValue(); 128 if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled) 129 { 130 // Get the enabled state from GPO. 131 _enabledStateIsGPOConfigured = true; 132 _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled; 133 } 134 else 135 { 136 _isEnabled = GeneralSettingsConfig.Enabled.FancyZones; 137 } 138 } 139 140 public override Dictionary<string, HotkeySettings[]> GetAllHotkeySettings() 141 { 142 var hotkeysDict = new Dictionary<string, HotkeySettings[]> 143 { 144 [ModuleName] = [EditorHotkey, NextTabHotkey, PrevTabHotkey], 145 }; 146 147 return hotkeysDict; 148 } 149 150 private GpoRuleConfigured _enabledGpoRuleConfiguration; 151 private bool _enabledStateIsGPOConfigured; 152 private bool _isEnabled; 153 private bool _shiftDrag; 154 private bool _mouseSwitch; 155 private bool _mouseMiddleButtonSpanningMultipleZones; 156 private bool _overrideSnapHotkeys; 157 private bool _moveWindowsAcrossMonitors; 158 private MoveWindowBehaviour _moveWindowBehaviour; 159 private OverlappingZonesAlgorithm _overlappingZonesAlgorithm; 160 private bool _displayOrWorkAreaChangeMoveWindows; 161 private bool _zoneSetChangeMoveWindows; 162 private bool _appLastZoneMoveWindows; 163 private bool _openWindowOnActiveMonitor; 164 private bool _spanZonesAcrossMonitors; 165 private bool _restoreSize; 166 private bool _quickLayoutSwitch; 167 private bool _flashZonesOnQuickLayoutSwitch; 168 private bool _useCursorPosEditorStartupScreen; 169 private bool _showOnAllMonitors; 170 private bool _makeDraggedWindowTransparent; 171 private bool _systemTheme; 172 private bool _showZoneNumber; 173 private bool _allowPopupWindowSnap; 174 private bool _allowChildWindowSnap; 175 private bool _disableRoundCornersOnSnap; 176 177 private int _highlightOpacity; 178 private string _excludedApps; 179 private HotkeySettings _editorHotkey; 180 private bool _windowSwitching; 181 private HotkeySettings _nextTabHotkey; 182 private HotkeySettings _prevTabHotkey; 183 private string _zoneInActiveColor; 184 private string _zoneBorderColor; 185 private string _zoneHighlightColor; 186 private string _zoneNumberColor; 187 188 public bool IsEnabled 189 { 190 get 191 { 192 return _isEnabled; 193 } 194 195 set 196 { 197 if (_enabledStateIsGPOConfigured) 198 { 199 // If it's GPO configured, shouldn't be able to change this state. 200 return; 201 } 202 203 if (value != _isEnabled) 204 { 205 _isEnabled = value; 206 207 // Set the status of FancyZones in the general settings configuration 208 GeneralSettingsConfig.Enabled.FancyZones = value; 209 OutGoingGeneralSettings snd = new OutGoingGeneralSettings(GeneralSettingsConfig); 210 211 SendConfigMSG(snd.ToString()); 212 OnPropertyChanged(nameof(IsEnabled)); 213 OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled)); 214 OnPropertyChanged(nameof(QuickSwitchEnabled)); 215 OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled)); 216 } 217 } 218 } 219 220 public bool IsEnabledGpoConfigured 221 { 222 get => _enabledStateIsGPOConfigured; 223 } 224 225 public bool SnapHotkeysCategoryEnabled 226 { 227 get 228 { 229 return _isEnabled && _overrideSnapHotkeys; 230 } 231 } 232 233 public bool QuickSwitchEnabled 234 { 235 get 236 { 237 return _isEnabled && _quickLayoutSwitch; 238 } 239 } 240 241 public bool WindowSwitchingCategoryEnabled 242 { 243 get 244 { 245 return _isEnabled && _windowSwitching; 246 } 247 } 248 249 public bool ShiftDrag 250 { 251 get 252 { 253 return _shiftDrag; 254 } 255 256 set 257 { 258 if (value != _shiftDrag) 259 { 260 _shiftDrag = value; 261 Settings.Properties.FancyzonesShiftDrag.Value = value; 262 NotifyPropertyChanged(); 263 } 264 } 265 } 266 267 public bool MouseSwitch 268 { 269 get 270 { 271 return _mouseSwitch; 272 } 273 274 set 275 { 276 if (value != _mouseSwitch) 277 { 278 _mouseSwitch = value; 279 Settings.Properties.FancyzonesMouseSwitch.Value = value; 280 NotifyPropertyChanged(); 281 } 282 } 283 } 284 285 public bool MouseMiddleClickSpanningMultipleZones 286 { 287 get 288 { 289 return _mouseMiddleButtonSpanningMultipleZones; 290 } 291 292 set 293 { 294 if (value != _mouseMiddleButtonSpanningMultipleZones) 295 { 296 _mouseMiddleButtonSpanningMultipleZones = value; 297 Settings.Properties.FancyzonesMouseMiddleClickSpanningMultipleZones.Value = value; 298 NotifyPropertyChanged(); 299 } 300 } 301 } 302 303 public string GetSettingsSubPath() 304 { 305 return settingsConfigFileFolder + "\\" + ModuleName; 306 } 307 308 public bool OverrideSnapHotkeys 309 { 310 get 311 { 312 return _overrideSnapHotkeys; 313 } 314 315 set 316 { 317 if (value != _overrideSnapHotkeys) 318 { 319 _overrideSnapHotkeys = value; 320 Settings.Properties.FancyzonesOverrideSnapHotkeys.Value = value; 321 NotifyPropertyChanged(); 322 OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled)); 323 } 324 } 325 } 326 327 public bool MoveWindowsAcrossMonitors 328 { 329 get 330 { 331 return _moveWindowsAcrossMonitors; 332 } 333 334 set 335 { 336 if (value != _moveWindowsAcrossMonitors) 337 { 338 _moveWindowsAcrossMonitors = value; 339 Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value = value; 340 NotifyPropertyChanged(); 341 } 342 } 343 } 344 345 public bool MoveWindowsBasedOnPosition 346 { 347 get 348 { 349 return _moveWindowBehaviour == MoveWindowBehaviour.MoveWindowBasedOnPosition; 350 } 351 352 set 353 { 354 var settingsValue = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value; 355 if (value != settingsValue) 356 { 357 _moveWindowBehaviour = value ? MoveWindowBehaviour.MoveWindowBasedOnPosition : MoveWindowBehaviour.MoveWindowBasedOnZoneIndex; 358 Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = value; 359 NotifyPropertyChanged(); 360 } 361 } 362 } 363 364 public bool MoveWindowsBasedOnZoneIndex 365 { 366 get 367 { 368 return _moveWindowBehaviour == MoveWindowBehaviour.MoveWindowBasedOnZoneIndex; 369 } 370 371 set 372 { 373 var settingsValue = Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value; 374 if (value == settingsValue) 375 { 376 _moveWindowBehaviour = value ? MoveWindowBehaviour.MoveWindowBasedOnZoneIndex : MoveWindowBehaviour.MoveWindowBasedOnPosition; 377 Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = !value; 378 NotifyPropertyChanged(); 379 } 380 } 381 } 382 383 public int OverlappingZonesAlgorithmIndex 384 { 385 get 386 { 387 return (int)_overlappingZonesAlgorithm; 388 } 389 390 set 391 { 392 if (value != (int)_overlappingZonesAlgorithm) 393 { 394 _overlappingZonesAlgorithm = (OverlappingZonesAlgorithm)value; 395 Settings.Properties.FancyzonesOverlappingZonesAlgorithm.Value = value; 396 NotifyPropertyChanged(); 397 } 398 } 399 } 400 401 public bool DisplayOrWorkAreaChangeMoveWindows 402 { 403 get 404 { 405 return _displayOrWorkAreaChangeMoveWindows; 406 } 407 408 set 409 { 410 if (value != _displayOrWorkAreaChangeMoveWindows) 411 { 412 _displayOrWorkAreaChangeMoveWindows = value; 413 Settings.Properties.FancyzonesDisplayOrWorkAreaChangeMoveWindows.Value = value; 414 NotifyPropertyChanged(); 415 } 416 } 417 } 418 419 public bool ZoneSetChangeMoveWindows 420 { 421 get 422 { 423 return _zoneSetChangeMoveWindows; 424 } 425 426 set 427 { 428 if (value != _zoneSetChangeMoveWindows) 429 { 430 _zoneSetChangeMoveWindows = value; 431 Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value = value; 432 NotifyPropertyChanged(); 433 } 434 } 435 } 436 437 public bool AppLastZoneMoveWindows 438 { 439 get 440 { 441 return _appLastZoneMoveWindows; 442 } 443 444 set 445 { 446 if (value != _appLastZoneMoveWindows) 447 { 448 _appLastZoneMoveWindows = value; 449 Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value = value; 450 NotifyPropertyChanged(); 451 } 452 } 453 } 454 455 public bool OpenWindowOnActiveMonitor 456 { 457 get 458 { 459 return _openWindowOnActiveMonitor; 460 } 461 462 set 463 { 464 if (value != _openWindowOnActiveMonitor) 465 { 466 _openWindowOnActiveMonitor = value; 467 Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value = value; 468 NotifyPropertyChanged(); 469 } 470 } 471 } 472 473 public bool RestoreSize 474 { 475 get 476 { 477 return _restoreSize; 478 } 479 480 set 481 { 482 if (value != _restoreSize) 483 { 484 _restoreSize = value; 485 Settings.Properties.FancyzonesRestoreSize.Value = value; 486 NotifyPropertyChanged(); 487 } 488 } 489 } 490 491 public bool QuickLayoutSwitch 492 { 493 get 494 { 495 return _quickLayoutSwitch; 496 } 497 498 set 499 { 500 if (value != _quickLayoutSwitch) 501 { 502 _quickLayoutSwitch = value; 503 Settings.Properties.FancyzonesQuickLayoutSwitch.Value = value; 504 NotifyPropertyChanged(); 505 OnPropertyChanged(nameof(QuickSwitchEnabled)); 506 } 507 } 508 } 509 510 public bool FlashZonesOnQuickSwitch 511 { 512 get 513 { 514 return _flashZonesOnQuickLayoutSwitch; 515 } 516 517 set 518 { 519 if (value != _flashZonesOnQuickLayoutSwitch) 520 { 521 _flashZonesOnQuickLayoutSwitch = value; 522 Settings.Properties.FancyzonesFlashZonesOnQuickSwitch.Value = value; 523 NotifyPropertyChanged(); 524 } 525 } 526 } 527 528 public bool UseCursorPosEditorStartupScreen 529 { 530 get 531 { 532 return _useCursorPosEditorStartupScreen; 533 } 534 535 set 536 { 537 if (value != _useCursorPosEditorStartupScreen) 538 { 539 _useCursorPosEditorStartupScreen = value; 540 Settings.Properties.UseCursorposEditorStartupscreen.Value = value; 541 NotifyPropertyChanged(); 542 } 543 } 544 } 545 546 public bool ShowOnAllMonitors 547 { 548 get 549 { 550 return _showOnAllMonitors; 551 } 552 553 set 554 { 555 if (value != _showOnAllMonitors) 556 { 557 _showOnAllMonitors = value; 558 Settings.Properties.FancyzonesShowOnAllMonitors.Value = value; 559 NotifyPropertyChanged(); 560 } 561 } 562 } 563 564 public bool SpanZonesAcrossMonitors 565 { 566 get 567 { 568 return _spanZonesAcrossMonitors; 569 } 570 571 set 572 { 573 if (value != _spanZonesAcrossMonitors) 574 { 575 _spanZonesAcrossMonitors = value; 576 Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value = value; 577 NotifyPropertyChanged(); 578 } 579 } 580 } 581 582 public bool MakeDraggedWindowsTransparent 583 { 584 get 585 { 586 return _makeDraggedWindowTransparent; 587 } 588 589 set 590 { 591 if (value != _makeDraggedWindowTransparent) 592 { 593 _makeDraggedWindowTransparent = value; 594 Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value = value; 595 NotifyPropertyChanged(); 596 } 597 } 598 } 599 600 public bool SystemTheme 601 { 602 get 603 { 604 return _systemTheme; 605 } 606 607 set 608 { 609 if (value != _systemTheme) 610 { 611 _systemTheme = value; 612 Settings.Properties.FancyzonesSystemTheme.Value = value; 613 NotifyPropertyChanged(); 614 } 615 } 616 } 617 618 public bool ShowZoneNumber 619 { 620 get 621 { 622 return _showZoneNumber; 623 } 624 625 set 626 { 627 if (value != _showZoneNumber) 628 { 629 _showZoneNumber = value; 630 Settings.Properties.FancyzonesShowZoneNumber.Value = value; 631 NotifyPropertyChanged(); 632 } 633 } 634 } 635 636 public bool AllowChildWindowSnap 637 { 638 get 639 { 640 return _allowChildWindowSnap; 641 } 642 643 set 644 { 645 if (value != _allowChildWindowSnap) 646 { 647 _allowChildWindowSnap = value; 648 Settings.Properties.FancyzonesAllowChildWindowSnap.Value = value; 649 NotifyPropertyChanged(); 650 } 651 } 652 } 653 654 public bool DisableRoundCornersOnWindowSnap 655 { 656 get 657 { 658 return _disableRoundCornersOnSnap; 659 } 660 661 set 662 { 663 if (_disableRoundCornersOnSnap != value) 664 { 665 _disableRoundCornersOnSnap = value; 666 Settings.Properties.FancyzonesDisableRoundCornersOnSnap.Value = value; 667 NotifyPropertyChanged(); 668 } 669 } 670 } 671 672 // For the following setters we use OrdinalIgnoreCase string comparison since 673 // we expect value to be a hex code. 674 public string ZoneHighlightColor 675 { 676 get 677 { 678 return _zoneHighlightColor; 679 } 680 681 set 682 { 683 value = SettingsUtilities.ToRGBHex(value); 684 if (!value.Equals(_zoneHighlightColor, StringComparison.OrdinalIgnoreCase)) 685 { 686 _zoneHighlightColor = value; 687 Settings.Properties.FancyzonesZoneHighlightColor.Value = value; 688 NotifyPropertyChanged(); 689 } 690 } 691 } 692 693 public string ZoneBorderColor 694 { 695 get 696 { 697 return _zoneBorderColor; 698 } 699 700 set 701 { 702 value = SettingsUtilities.ToRGBHex(value); 703 if (!value.Equals(_zoneBorderColor, StringComparison.OrdinalIgnoreCase)) 704 { 705 _zoneBorderColor = value; 706 Settings.Properties.FancyzonesBorderColor.Value = value; 707 NotifyPropertyChanged(); 708 } 709 } 710 } 711 712 public string ZoneInActiveColor 713 { 714 get 715 { 716 return _zoneInActiveColor; 717 } 718 719 set 720 { 721 value = SettingsUtilities.ToRGBHex(value); 722 if (!value.Equals(_zoneInActiveColor, StringComparison.OrdinalIgnoreCase)) 723 { 724 _zoneInActiveColor = value; 725 Settings.Properties.FancyzonesInActiveColor.Value = value; 726 NotifyPropertyChanged(); 727 } 728 } 729 } 730 731 public string ZoneNumberColor 732 { 733 get 734 { 735 return _zoneNumberColor; 736 } 737 738 set 739 { 740 value = SettingsUtilities.ToRGBHex(value); 741 if (!value.Equals(_zoneNumberColor, StringComparison.OrdinalIgnoreCase)) 742 { 743 _zoneNumberColor = value; 744 Settings.Properties.FancyzonesNumberColor.Value = value; 745 NotifyPropertyChanged(); 746 } 747 } 748 } 749 750 public int HighlightOpacity 751 { 752 get 753 { 754 return _highlightOpacity; 755 } 756 757 set 758 { 759 if (value != _highlightOpacity) 760 { 761 _highlightOpacity = value; 762 Settings.Properties.FancyzonesHighlightOpacity.Value = value; 763 NotifyPropertyChanged(); 764 } 765 } 766 } 767 768 public HotkeySettings EditorHotkey 769 { 770 get 771 { 772 return _editorHotkey; 773 } 774 775 set 776 { 777 if (value != _editorHotkey) 778 { 779 if (value == null) 780 { 781 _editorHotkey = FZConfigProperties.DefaultEditorHotkeyValue; 782 } 783 else 784 { 785 _editorHotkey = value; 786 } 787 788 Settings.Properties.FancyzonesEditorHotkey.Value = _editorHotkey; 789 NotifyPropertyChanged(); 790 } 791 } 792 } 793 794 public bool WindowSwitching 795 { 796 get 797 { 798 return _windowSwitching; 799 } 800 801 set 802 { 803 if (value != _windowSwitching) 804 { 805 _windowSwitching = value; 806 807 Settings.Properties.FancyzonesWindowSwitching.Value = _windowSwitching; 808 NotifyPropertyChanged(); 809 OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled)); 810 } 811 } 812 } 813 814 public HotkeySettings NextTabHotkey 815 { 816 get 817 { 818 return _nextTabHotkey; 819 } 820 821 set 822 { 823 if (value != _nextTabHotkey) 824 { 825 if (value == null) 826 { 827 _nextTabHotkey = FZConfigProperties.DefaultNextTabHotkeyValue; 828 } 829 else 830 { 831 _nextTabHotkey = value; 832 } 833 834 Settings.Properties.FancyzonesNextTabHotkey.Value = _nextTabHotkey; 835 NotifyPropertyChanged(); 836 } 837 } 838 } 839 840 public HotkeySettings PrevTabHotkey 841 { 842 get 843 { 844 return _prevTabHotkey; 845 } 846 847 set 848 { 849 if (value != _prevTabHotkey) 850 { 851 if (value == null) 852 { 853 _prevTabHotkey = FZConfigProperties.DefaultPrevTabHotkeyValue; 854 } 855 else 856 { 857 _prevTabHotkey = value; 858 } 859 860 Settings.Properties.FancyzonesPrevTabHotkey.Value = _prevTabHotkey; 861 NotifyPropertyChanged(); 862 } 863 } 864 } 865 866 public string ExcludedApps 867 { 868 get 869 { 870 return _excludedApps; 871 } 872 873 set 874 { 875 if (value != _excludedApps) 876 { 877 _excludedApps = value; 878 Settings.Properties.FancyzonesExcludedApps.Value = value; 879 NotifyPropertyChanged(); 880 } 881 } 882 } 883 884 public bool Windows11 => _windows11; 885 886 private void LaunchEditor() 887 { 888 // send message to launch the zones editor; 889 SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}"); 890 } 891 892 public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 893 { 894 OnPropertyChanged(propertyName); 895 SettingsUtils.SaveSettings(Settings.ToJsonString(), GetSettingsSubPath()); 896 } 897 898 public void RefreshEnabledState() 899 { 900 InitializeEnabledValue(); 901 OnPropertyChanged(nameof(IsEnabled)); 902 OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled)); 903 OnPropertyChanged(nameof(QuickSwitchEnabled)); 904 OnPropertyChanged(nameof(WindowSwitchingCategoryEnabled)); 905 } 906 } 907 }