Skip to content

Commit 1284afd

Browse files
lgc2333codex
andcommitted
feat(volume): add option to sync volume flyout with media flyout
Adds a volume setting to show and hide the volume flyout together with the media flyout when it is opened from the tray icon or the taskbar widget. Co-authored-by: Codex <codex@openai.com>
1 parent cf59555 commit 1284afd

7 files changed

Lines changed: 67 additions & 2 deletions

File tree

‎FluentFlyoutWPF/Controls/TaskbarWidgetControl.xaml.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
251251
if (_mainWindow == null) return;
252252

253253
// toggle main flyout when clicked
254-
_mainWindow.ShowMediaFlyout(toggleMode: true, forceShow: true);
254+
_mainWindow.ShowMediaFlyoutWithVolume(toggleMode: true, forceShow: true);
255255
}
256256

257257
private void MainBorder_MouseWheel(object sender, MouseWheelEventArgs e)

‎FluentFlyoutWPF/MainWindow.xaml.cs‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,29 @@ private void ShowVolumeFlyout()
994994
volumeMixerWindow?.ShowFlyout();
995995
}
996996

997+
/// <summary>
998+
/// Shows the media flyout, optionally together with the volume flyout when
999+
/// "sync with media flyout" is enabled. Used by manual triggers (tray icon, taskbar widget)
1000+
/// so both flyouts open and close as one.
1001+
/// </summary>
1002+
public void ShowMediaFlyoutWithVolume(bool toggleMode = false, bool forceShow = false)
1003+
{
1004+
bool shouldShowVolumeFlyoutWithMedia = GetActiveMediaSession() != null
1005+
&& (forceShow || SettingsManager.Current.MediaFlyoutEnabled)
1006+
&& !FullscreenDetector.IsFullscreenApplicationRunning()
1007+
&& SettingsManager.Current.VolumeControlEnabled
1008+
&& SettingsManager.Current.VolumeControlSyncWithMediaFlyout;
1009+
bool isToggleClose = toggleMode && Visibility == Visibility.Visible && !_isHiding;
1010+
1011+
if (shouldShowVolumeFlyoutWithMedia && isToggleClose)
1012+
volumeMixerWindow?.HideFlyout();
1013+
1014+
ShowMediaFlyout(toggleMode, forceShow);
1015+
1016+
if (shouldShowVolumeFlyoutWithMedia && !isToggleClose)
1017+
ShowVolumeFlyout();
1018+
}
1019+
9971020
public async void ShowMediaFlyout(bool toggleMode = false, bool forceShow = false)
9981021
{
9991022
var activeSession = GetActiveMediaSession();
@@ -1977,7 +2000,7 @@ private void nIcon_LeftClick(Wpf.Ui.Tray.Controls.NotifyIcon sender, RoutedEvent
19772000
//ThemeService themeService = new ThemeService();
19782001
//themeService.ChangeTheme(MicaWPF.Core.Enums.WindowsTheme.Light);
19792002
}
1980-
else if (SettingsManager.Current.NIconLeftClick == 1) ShowMediaFlyout();
2003+
else if (SettingsManager.Current.NIconLeftClick == 1) ShowMediaFlyoutWithVolume();
19812004
}
19822005

19832006
private Task PauseOtherSessions(MediaSession currentMediaSession)

‎FluentFlyoutWPF/Pages/VolumeMixerPage.xaml‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@
7171
<ui:ToggleSwitch IsChecked="{Binding VolumeControlAboveMediaFlyout, Mode=TwoWay}" />
7272
</ui:CardControl>
7373

74+
<ui:CardControl x:Name="VolumeSyncWithMediaFlyoutTitleCard" Tag="Indexable" Icon="{ui:SymbolIcon ArrowSync24}" Margin="0,0,0,3">
75+
<ui:CardControl.Header>
76+
<StackPanel Orientation="Vertical">
77+
<TextBlock Text="{DynamicResource VolumeSyncWithMediaFlyoutTitle}" FontSize="14" FontWeight="Regular" VerticalAlignment="Center" />
78+
<TextBlock Text="{DynamicResource VolumeSyncWithMediaFlyoutDescription}" FontSize="12" Opacity="0.5" />
79+
</StackPanel>
80+
</ui:CardControl.Header>
81+
<ui:ToggleSwitch IsChecked="{Binding VolumeControlSyncWithMediaFlyout, Mode=TwoWay}" />
82+
</ui:CardControl>
83+
7484
<ui:CardControl x:Name="VolumeFlyoutStayDurationTitleCard" Tag="Indexable" Grid.Row="3" Icon="{ui:SymbolIcon Timer24}" Margin="0,0,0,12">
7585
<ui:CardControl.Header>
7686
<StackPanel Orientation="Vertical">

‎FluentFlyoutWPF/Resources/Localization/Dictionary-en-US.xaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,6 @@ You can help contribute translations on</System:String>
293293
<System:String x:Key="VolumeMixerHighlightDescription">See which apps are currently outputting audio</System:String>
294294
<System:String x:Key="MasterVolumeText">Master volume</System:String>
295295
<System:String x:Key="OpenMediaPlayerText">Open media player</System:String>
296+
<System:String x:Key="VolumeSyncWithMediaFlyoutTitle">Always show and hide with Media Flyout</System:String>
297+
<System:String x:Key="VolumeSyncWithMediaFlyoutDescription">Show or hide the volume flyout together with the media flyout when opened from the tray icon or taskbar widget.</System:String>
296298
</ResourceDictionary>

‎FluentFlyoutWPF/Resources/Localization/Dictionary-zh-CN.xaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,7 @@
296296
<system:String x:Key="OnboardingTitle">快速入门</system:String>
297297
<system:String x:Key="SupporterTitle">赞助者</system:String>
298298
<system:String x:Key="SupporterDescription">谢谢你!</system:String>
299+
<system:String x:Key="VolumeSyncWithMediaFlyoutTitle">随媒体浮窗显示</system:String>
300+
<system:String x:Key="VolumeSyncWithMediaFlyoutDescription" xml:space="preserve">从任务栏小组件唤起或收起媒体浮窗时一同显隐音量浮窗
301+
如“单击托盘图标时行为”设为“显示媒体浮窗”,触发时音量浮窗也将一同显示</system:String>
299302
</ResourceDictionary>

‎FluentFlyoutWPF/ViewModels/UserSettings.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,9 @@ public string TaskbarWidgetScrollingTextSpeedText
597597
[ObservableProperty]
598598
public partial bool VolumeControlAboveMediaFlyout { get; set; }
599599

600+
[ObservableProperty]
601+
public partial bool VolumeControlSyncWithMediaFlyout { get; set; }
602+
600603
[ObservableProperty]
601604
[NotifyPropertyChangedFor(nameof(VolumeControlDurationText))]
602605
public partial int VolumeControlDuration { get; set; }
@@ -777,6 +780,7 @@ public UserSettings()
777780
TaskbarVisualizerBaselineAutoHide = false;
778781
VolumeControlEnabled = false;
779782
VolumeControlAboveMediaFlyout = false;
783+
VolumeControlSyncWithMediaFlyout = false;
780784
VolumeControlDuration = 3000;
781785
VolumeMixerEnabled = false;
782786
VolumeMixerHighlightActiveApps = false;

‎FluentFlyoutWPF/Windows/VolumeMixerWindow.xaml.cs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,29 @@ public async void ShowFlyout(bool startExpanded = false)
172172
}
173173
}
174174

175+
/// <summary>
176+
/// Hides the flyout immediately, without waiting for the stay duration.
177+
/// Used when the volume flyout is synced with the media flyout.
178+
/// </summary>
179+
public async void HideFlyout()
180+
{
181+
if (_isHiding)
182+
return;
183+
184+
_cts.Cancel();
185+
_mainWindow.CloseAnimation(this);
186+
_isHiding = true;
187+
_lastFlyoutTime = 0;
188+
await Task.Delay(MainWindow.getDuration());
189+
190+
if (!_isHiding)
191+
return;
192+
193+
WindowHelper.SetVisibility(this, false);
194+
ViewModel.IsExpanded = false;
195+
_ = Task.Run(() => ShowVolumeOsd());
196+
}
197+
175198
private void OnViewModelPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
176199
{
177200
if (e.PropertyName == nameof(VolumeMixerViewModel.IsExpanded))

0 commit comments

Comments
 (0)