13
13
using SoundSwitch . Audio . Manager . Interop . Enum ;
14
14
using SoundSwitch . Common . Framework . Audio . Device ;
15
15
using SoundSwitch . Framework . Configuration ;
16
+ using SoundSwitch . Framework . Profile . Hotkey ;
16
17
using SoundSwitch . Framework . Profile . Trigger ;
17
18
using SoundSwitch . Framework . WinApi ;
18
- using SoundSwitch . Framework . WinApi . Keyboard ;
19
19
using SoundSwitch . Localization ;
20
20
using SoundSwitch . Model ;
21
21
using SoundSwitch . Util ;
@@ -26,75 +26,94 @@ public class ProfileManager
26
26
{
27
27
public delegate void ShowError ( string errorMessage , string errorTitle ) ;
28
28
29
- private readonly WindowMonitor _windowMonitor ;
30
- private readonly AudioSwitcher _audioSwitcher ;
31
- private readonly IAudioDeviceLister _activeDeviceLister ;
32
- private readonly ShowError _showError ;
33
- private readonly TriggerFactory _triggerFactory ;
29
+ private readonly WindowMonitor _windowMonitor ;
30
+ private readonly AudioSwitcher _audioSwitcher ;
31
+ private readonly IAudioDeviceLister _activeDeviceLister ;
32
+ private readonly ShowError _showError ;
33
+ private readonly TriggerFactory _triggerFactory ;
34
34
private readonly NotificationManager . NotificationManager _notificationManager ;
35
35
36
36
private Profile ? _steamProfile ;
37
37
38
38
private readonly Dictionary < User32 . NativeMethods . HWND , Profile > _activeWindowsTrigger = new ( ) ;
39
39
40
- private readonly Dictionary < HotKey , Profile > _profilesByHotkey = new ( ) ;
41
40
private readonly Dictionary < string , ( Profile Profile , Trigger . Trigger Trigger ) > _profileByApplication = new ( ) ;
42
41
private readonly Dictionary < string , ( Profile Profile , Trigger . Trigger Trigger ) > _profilesByWindowName = new ( ) ;
43
- private readonly Dictionary < string , ( Profile Profile , Trigger . Trigger Trigger ) > _profilesByUwpApp = new ( ) ;
42
+ private readonly Dictionary < string , ( Profile Profile , Trigger . Trigger Trigger ) > _profilesByUwpApp = new ( ) ;
43
+
44
+ private readonly ProfileHotkeyManager _profileHotkeyManager ;
44
45
45
46
46
47
public IReadOnlyCollection < Profile > Profiles => AppConfigs . Configuration . Profiles ;
47
48
48
- public ProfileManager ( WindowMonitor windowMonitor ,
49
- AudioSwitcher audioSwitcher ,
50
- IAudioDeviceLister activeDeviceLister ,
51
- ShowError showError ,
52
- TriggerFactory triggerFactory ,
49
+ public ProfileManager ( WindowMonitor windowMonitor ,
50
+ AudioSwitcher audioSwitcher ,
51
+ IAudioDeviceLister activeDeviceLister ,
52
+ ShowError showError ,
53
+ TriggerFactory triggerFactory ,
53
54
NotificationManager . NotificationManager notificationManager )
54
55
{
55
- _windowMonitor = windowMonitor ;
56
- _audioSwitcher = audioSwitcher ;
57
- _activeDeviceLister = activeDeviceLister ;
58
- _showError = showError ;
59
- _triggerFactory = triggerFactory ;
56
+ _windowMonitor = windowMonitor ;
57
+ _audioSwitcher = audioSwitcher ;
58
+ _activeDeviceLister = activeDeviceLister ;
59
+ _showError = showError ;
60
+ _triggerFactory = triggerFactory ;
60
61
_notificationManager = notificationManager ;
62
+ _profileHotkeyManager = new ( this ) ;
61
63
}
62
64
63
- private void RegisterTriggers ( Profile profile , bool onInit = false )
65
+ private bool RegisterTriggers ( Profile profile , bool onInit = false )
64
66
{
67
+ var success = true ;
65
68
foreach ( var trigger in profile . Triggers )
66
69
{
67
- trigger . Type . Switch ( ( ) => { _profilesByHotkey . Add ( trigger . HotKey , profile ) ; } ,
68
- ( ) => { _profilesByWindowName . Add ( trigger . WindowName . ToLower ( ) , ( profile , trigger ) ) ; } ,
69
- ( ) => { _profileByApplication . Add ( trigger . ApplicationPath . ToLower ( ) , ( profile , trigger ) ) ; } ,
70
- ( ) => { _steamProfile = profile ; } ,
70
+ success &= trigger . Type . Match ( ( ) => _profileHotkeyManager . Add ( trigger . HotKey , profile ) ,
71
+ ( ) =>
72
+ {
73
+ _profilesByWindowName . Add ( trigger . WindowName . ToLower ( ) , ( profile , trigger ) ) ;
74
+ return true ;
75
+ } ,
76
+ ( ) =>
77
+ {
78
+ _profileByApplication . Add ( trigger . ApplicationPath . ToLower ( ) , ( profile , trigger ) ) ;
79
+ return true ;
80
+ } ,
81
+ ( ) =>
82
+ {
83
+ _steamProfile = profile ;
84
+ return true ;
85
+ } ,
71
86
( ) =>
72
87
{
73
88
if ( ! onInit )
74
89
{
75
- return ;
90
+ return true ;
76
91
}
77
92
78
93
SwitchAudio ( profile ) ;
79
- } , ( ) => { _profilesByUwpApp . Add ( trigger . WindowName . ToLower ( ) , ( profile , trigger ) ) ; } ,
80
- ( ) => { } ) ;
94
+ return true ;
95
+ } , ( ) =>
96
+ {
97
+ _profilesByUwpApp . Add ( trigger . WindowName . ToLower ( ) , ( profile , trigger ) ) ;
98
+ return true ;
99
+ } ,
100
+ ( ) => true ) ;
101
+
81
102
}
103
+
104
+ return success ;
82
105
}
83
106
84
107
private void UnRegisterTriggers ( Profile profile )
85
108
{
86
109
foreach ( var trigger in profile . Triggers )
87
110
{
88
- trigger . Type . Switch ( ( ) =>
89
- {
90
- WindowsAPIAdapter . UnRegisterHotKey ( trigger . HotKey ) ;
91
- _profilesByHotkey . Remove ( trigger . HotKey ) ;
92
- } ,
111
+ trigger . Type . Switch ( ( ) => { _profileHotkeyManager . Remove ( trigger . HotKey , profile ) ; } ,
93
112
( ) => { _profilesByWindowName . Remove ( trigger . WindowName . ToLower ( ) ) ; } ,
94
113
( ) => { _profileByApplication . Remove ( trigger . ApplicationPath . ToLower ( ) ) ; } ,
95
114
( ) => { _steamProfile = null ; } , ( ) => { } ,
96
115
( ) => { _profilesByUwpApp . Remove ( trigger . WindowName . ToLower ( ) ) ; } ,
97
- ( ) => { } ) ;
116
+ ( ) => { } ) ;
98
117
}
99
118
}
100
119
@@ -104,18 +123,10 @@ private void UnRegisterTriggers(Profile profile)
104
123
/// <returns></returns>
105
124
public Result < Profile [ ] , VoidSuccess > Init ( )
106
125
{
107
- foreach ( var profile in AppConfigs . Configuration . Profiles )
108
- {
109
- RegisterTriggers ( profile , true ) ;
110
- }
126
+ var errors = AppConfigs . Configuration . Profiles . Where ( profile => ! RegisterTriggers ( profile , true ) ) . ToArray ( ) ;
111
127
112
128
RegisterEvents ( ) ;
113
129
114
- var errors = _profilesByHotkey
115
- . Where ( pair => ! WindowsAPIAdapter . RegisterHotKey ( pair . Key ) )
116
- . Select ( pair => pair . Value )
117
- . ToArray ( ) ;
118
-
119
130
InitializeProfileExistingProcess ( ) ;
120
131
121
132
if ( errors . Length > 0 )
@@ -139,12 +150,6 @@ private void RegisterEvents()
139
150
if ( HandleWindowName ( @event ) ) return ;
140
151
} ;
141
152
142
- WindowsAPIAdapter . HotKeyPressed += ( sender , args ) =>
143
- {
144
- if ( ! _profilesByHotkey . TryGetValue ( args . HotKey , out var profile ) )
145
- return ;
146
- SwitchAudio ( profile ) ;
147
- } ;
148
153
WindowsAPIAdapter . WindowDestroyed += ( sender , @event ) => { RestoreState ( @event . Hwnd ) ; } ;
149
154
}
150
155
@@ -209,18 +214,18 @@ private bool SaveCurrentState(User32.NativeMethods.HWND windowHandle, Profile pr
209
214
return false ;
210
215
}
211
216
212
- var communication = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eRender , ERole . eCommunications ) ;
213
- var playback = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eRender , ERole . eMultimedia ) ;
214
- var recording = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eCapture , ERole . eMultimedia ) ;
217
+ var communication = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eRender , ERole . eCommunications ) ;
218
+ var playback = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eRender , ERole . eMultimedia ) ;
219
+ var recording = _audioSwitcher . GetDefaultAudioEndpoint ( EDataFlow . eCapture , ERole . eMultimedia ) ;
215
220
216
221
var currentState = new Profile
217
222
{
218
223
AlsoSwitchDefaultDevice = true ,
219
- Name = SettingsStrings . profile_trigger_restoreDevices_title ,
220
- Communication = communication ,
221
- Playback = playback ,
222
- Recording = recording ,
223
- NotifyOnActivation = profile . NotifyOnActivation
224
+ Name = SettingsStrings . profile_trigger_restoreDevices_title ,
225
+ Communication = communication ,
226
+ Playback = playback ,
227
+ Recording = recording ,
228
+ NotifyOnActivation = profile . NotifyOnActivation
224
229
} ;
225
230
_activeWindowsTrigger . Add ( windowHandle , currentState ) ;
226
231
return true ;
@@ -283,7 +288,7 @@ private void SwitchAudio(Profile profile, uint processId)
283
288
_audioSwitcher . SwitchProcessTo (
284
289
deviceToUse . Id ,
285
290
device . Role ,
286
- ( EDataFlow ) deviceToUse . Type ,
291
+ ( EDataFlow ) deviceToUse . Type ,
287
292
processId ) ;
288
293
289
294
if ( profile . AlsoSwitchDefaultDevice )
@@ -317,7 +322,7 @@ public void SwitchAudio(Profile profile)
317
322
/// <returns></returns>
318
323
public IEnumerable < ITriggerDefinition > AvailableTriggers ( )
319
324
{
320
- var triggers = Profiles . SelectMany ( profile => profile . Triggers ) . GroupBy ( trigger => trigger . Type ) . ToDictionary ( grouping => grouping . Key , grouping => grouping . Count ( ) ) ;
325
+ var triggers = Profiles . SelectMany ( profile => profile . Triggers ) . GroupBy ( trigger => trigger . Type ) . ToDictionary ( grouping => grouping . Key , grouping => grouping . Count ( ) ) ;
321
326
var triggerFactory = new TriggerFactory ( ) ;
322
327
return triggerFactory . AllImplementations
323
328
. Where ( pair =>
@@ -353,7 +358,7 @@ public Result<string, VoidSuccess> AddProfile(Profile profile)
353
358
/// </summary>
354
359
public Result < string , VoidSuccess > UpdateProfile ( Profile oldProfile , Profile newProfile )
355
360
{
356
- DeleteProfiles ( new [ ] { oldProfile } ) ;
361
+ DeleteProfiles ( new [ ] { oldProfile } ) ;
357
362
return ValidateProfile ( newProfile )
358
363
. Map ( success =>
359
364
{
@@ -394,7 +399,7 @@ private Result<string, VoidSuccess> ValidateProfile(Profile profile)
394
399
{
395
400
var error = trigger . Type . Match ( ( ) =>
396
401
{
397
- if ( trigger . HotKey == null || _profilesByHotkey . ContainsKey ( trigger . HotKey ) || ! WindowsAPIAdapter . RegisterHotKey ( trigger . HotKey ) )
402
+ if ( trigger . HotKey == null || ! _profileHotkeyManager . IsValidHotkey ( trigger . HotKey ) )
398
403
{
399
404
return string . Format ( SettingsStrings . profile_error_hotkey , trigger . HotKey ) ;
400
405
}
@@ -454,7 +459,7 @@ private Result<string, VoidSuccess> ValidateAddProfile(ProfileSetting profile)
454
459
return SettingsStrings . profile_error_needPlaybackOrRecording ;
455
460
}
456
461
457
- if ( profile . HotKey != null && _profilesByHotkey . ContainsKey ( profile . HotKey ) )
462
+ if ( profile . HotKey != null && ! _profileHotkeyManager . IsValidHotkey ( profile . HotKey ) )
458
463
{
459
464
return string . Format ( SettingsStrings . profile_error_hotkey , profile . HotKey ) ;
460
465
}
@@ -484,8 +489,8 @@ private Result<string, VoidSuccess> ValidateAddProfile(ProfileSetting profile)
484
489
/// </summary>
485
490
public Result < Profile [ ] , VoidSuccess > DeleteProfiles ( IEnumerable < Profile > profilesToDelete )
486
491
{
487
- var errors = new List < Profile > ( ) ;
488
- var profiles = profilesToDelete . ToArray ( ) ;
492
+ var errors = new List < Profile > ( ) ;
493
+ var profiles = profilesToDelete . ToArray ( ) ;
489
494
var resetProcessAudio = profiles . Any ( profile => profile . Triggers . Any ( trigger => trigger . Type == TriggerFactory . Enum . Process || trigger . Type == TriggerFactory . Enum . Window ) ) ;
490
495
foreach ( var profile in profiles )
491
496
{
@@ -540,7 +545,7 @@ private void InitializeProfileExistingProcess()
540
545
{
541
546
var handle = User32 . NativeMethods . HWND . Cast ( process . Handle ) ;
542
547
SaveCurrentState ( handle , profile . Profile , profile . Trigger ) ;
543
- SwitchAudio ( profile . Profile , ( uint ) process . Id ) ;
548
+ SwitchAudio ( profile . Profile , ( uint ) process . Id ) ;
544
549
}
545
550
}
546
551
catch ( Win32Exception )
0 commit comments