mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
窗口失去焦点时使标题和标题栏按钮变灰 (#635)
* feat: 窗口失去焦点时使标题和标题栏按钮便灰 * chore: 删除一个 hack,增加一个 hack * UI: 微调 ExpandedModeThresholdWidth * fix: 修复不显示边框颜色时深色模式的边框是纯黑而不是半透明的问题 * chore: Debug 配置允许有编译警告 便于实验和调试
This commit is contained in:
parent
fdcbebe963
commit
6f88d9d153
14 changed files with 78 additions and 19 deletions
|
|
@ -12,7 +12,6 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<!-- 'type' : class 'type1' needs to have dll-interface to be used by clients of class 'type2' -->
|
||||
<DisableSpecificWarnings>4251</DisableSpecificWarnings>
|
||||
<!-- /utf-8: 源代码使用 UTF-8 格式 -->
|
||||
|
|
|
|||
|
|
@ -29,12 +29,13 @@ void CaptionButtonsControl::HoverButton(CaptionButton button) {
|
|||
} else {
|
||||
_allInNormal = false;
|
||||
|
||||
const wchar_t* activeState = _isWindowActive ? L"Normal" : L"NotActive";
|
||||
VisualStateManager::GoToState(MinimizeButton(),
|
||||
button == CaptionButton::Minimize ? L"PointerOver" : L"Normal", false);
|
||||
button == CaptionButton::Minimize ? L"PointerOver" : activeState, false);
|
||||
VisualStateManager::GoToState(MaximizeButton(),
|
||||
button == CaptionButton::Maximize ? L"PointerOver" : L"Normal", false);
|
||||
VisualStateManager::GoToState(CloseButton(),
|
||||
button == CaptionButton::Close ? L"PointerOver" : L"Normal", false);
|
||||
button == CaptionButton::Maximize ? L"PointerOver" : activeState, false);
|
||||
VisualStateManager::GoToState(CloseButton(),
|
||||
button == CaptionButton::Close ? L"PointerOver" : activeState, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +115,10 @@ void CaptionButtonsControl::LeaveButtons() {
|
|||
}
|
||||
_allInNormal = true;
|
||||
|
||||
VisualStateManager::GoToState(MinimizeButton(), L"Normal", true);
|
||||
VisualStateManager::GoToState(MaximizeButton(), L"Normal", true);
|
||||
VisualStateManager::GoToState(CloseButton(), L"Normal", true);
|
||||
const wchar_t* activeState = _isWindowActive ? L"Normal" : L"NotActive";
|
||||
VisualStateManager::GoToState(MinimizeButton(), activeState, true);
|
||||
VisualStateManager::GoToState(MaximizeButton(), activeState, true);
|
||||
VisualStateManager::GoToState(CloseButton(), activeState, true);
|
||||
}
|
||||
|
||||
void CaptionButtonsControl::IsWindowMaximized(bool value) {
|
||||
|
|
@ -125,10 +127,18 @@ void CaptionButtonsControl::IsWindowMaximized(bool value) {
|
|||
}
|
||||
|
||||
if (VisualStateManager::GoToState(MaximizeButton(),
|
||||
value ? L"WindowStateMaximized" : L"WindowStateNormal", false))
|
||||
{
|
||||
value ? L"WindowStateMaximized" : L"WindowStateNormal", false)) {
|
||||
_isWindowMaximized = value;
|
||||
}
|
||||
}
|
||||
|
||||
void CaptionButtonsControl::IsWindowActive(bool value) {
|
||||
_isWindowActive = value;
|
||||
|
||||
const wchar_t* activeState = value ? L"Normal" : L"NotActive";
|
||||
VisualStateManager::GoToState(MinimizeButton(), activeState, false);
|
||||
VisualStateManager::GoToState(MaximizeButton(), activeState, false);
|
||||
VisualStateManager::GoToState(CloseButton(), activeState, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ struct CaptionButtonsControl : CaptionButtonsControlT<CaptionButtonsControl> {
|
|||
void LeaveButtons();
|
||||
|
||||
void IsWindowMaximized(bool value);
|
||||
void IsWindowActive(bool value);
|
||||
|
||||
private:
|
||||
std::optional<CaptionButton> _pressedButton;
|
||||
// 用于避免重复设置状态
|
||||
bool _allInNormal = true;
|
||||
bool _isWindowMaximized = false;
|
||||
bool _isWindowActive = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,6 @@ namespace Magpie.App {
|
|||
void LeaveButtons();
|
||||
|
||||
void IsWindowMaximized(Boolean value);
|
||||
void IsWindowActive(Boolean value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
<SolidColorBrush x:Key="CaptionButtonForegroundPressed"
|
||||
Opacity="0.7"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonForegroundNotActive"
|
||||
Opacity="0.38"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver"
|
||||
Opacity="0.06"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
|
|
@ -37,6 +40,9 @@
|
|||
<SolidColorBrush x:Key="CaptionButtonForegroundPressed"
|
||||
Opacity="0.7"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonForegroundNotActive"
|
||||
Opacity="0.35"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
<SolidColorBrush x:Key="CaptionButtonBackgroundPointerOver"
|
||||
Opacity="0.06"
|
||||
Color="{StaticResource CaptionButtonForegroundColor}" />
|
||||
|
|
@ -105,7 +111,11 @@
|
|||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Disabled" />
|
||||
<VisualState x:Name="NotActive">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ButtonIcon.Foreground" Value="{ThemeResource CaptionButtonForegroundNotActive}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
<VisualStateGroup x:Name="MinMaxStates">
|
||||
|
|
@ -117,7 +127,6 @@
|
|||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
|
|
|
|||
|
|
@ -89,10 +89,10 @@ void MainPage::InitializeComponent() {
|
|||
}
|
||||
|
||||
void MainPage::Loaded(IInspectable const&, RoutedEventArgs const&) {
|
||||
MUXC::NavigationView nv = RootNavigationView();
|
||||
|
||||
// 修复 WinUI 的汉堡菜单的尺寸 bug
|
||||
nv.PaneDisplayMode(MUXC::NavigationViewPaneDisplayMode::Auto);
|
||||
// 消除焦点框
|
||||
IsTabStop(true);
|
||||
Focus(FocusState::Programmatic);
|
||||
IsTabStop(false);
|
||||
|
||||
// 设置 NavigationView 内的 Tooltip 的主题
|
||||
XamlUtils::UpdateThemeOfTooltips(*this, ActualTheme());
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
Canvas.ZIndex="0"
|
||||
CompactModeThresholdWidth="0"
|
||||
DisplayModeChanged="NavigationView_DisplayModeChanged"
|
||||
ExpandedModeThresholdWidth="950"
|
||||
IsBackButtonVisible="Collapsed"
|
||||
ItemInvoked="NavigationView_ItemInvoked"
|
||||
PaneClosing="NavigationView_PaneClosing"
|
||||
|
|
|
|||
|
|
@ -38,4 +38,9 @@ void TitleBarControl::Loading(FrameworkElement const&, IInspectable const&) {
|
|||
});
|
||||
}
|
||||
|
||||
void TitleBarControl::IsWindowActive(bool value) {
|
||||
VisualStateManager::GoToState(*this, value ? L"Active" : L"NotActive", false);
|
||||
CaptionButtons().IsWindowActive(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ struct TitleBarControl : TitleBarControlT<TitleBarControl> {
|
|||
_propertyChangedEvent.remove(token);
|
||||
}
|
||||
|
||||
void IsWindowActive(bool value);
|
||||
|
||||
private:
|
||||
Imaging::SoftwareBitmapSource _logo{ nullptr };
|
||||
event<PropertyChangedEventHandler> _propertyChangedEvent;
|
||||
|
|
|
|||
|
|
@ -4,5 +4,7 @@ namespace Magpie.App {
|
|||
|
||||
Windows.UI.Xaml.Media.Imaging.SoftwareBitmapSource Logo { get; };
|
||||
CaptionButtonsControl CaptionButtons { get; };
|
||||
|
||||
void IsWindowActive(Boolean value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@
|
|||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Source="{x:Bind Logo, Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,2"
|
||||
<TextBlock x:Name="TitleTextBlock"
|
||||
Margin="0,0,0,2"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="12"
|
||||
Text="Magpie" />
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
VerticalAlignment="Top" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="VisualStates">
|
||||
<VisualStateGroup x:Name="TitleStates">
|
||||
<VisualStateGroup.Transitions>
|
||||
<VisualTransition From="Expanded"
|
||||
To="Compact">
|
||||
|
|
@ -72,6 +73,14 @@
|
|||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="ActiveStates">
|
||||
<VisualState x:Name="Active" />
|
||||
<VisualState x:Name="NotActive">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="TitleTextBlock.Foreground" Value="#8E8E8E" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
|||
|
|
@ -188,6 +188,11 @@ LRESULT MainWindow::_MessageHandler(UINT msg, WPARAM wParam, LPARAM lParam) noex
|
|||
}
|
||||
break;
|
||||
}
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
_content.TitleBar().IsWindowActive(LOWORD(wParam) != WA_INACTIVE);
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
{
|
||||
XamlApp::Get().SaveSettings();
|
||||
|
|
|
|||
|
|
@ -503,7 +503,14 @@ private:
|
|||
//
|
||||
// 有的软件自己绘制了假的上边框,如 Chromium 系、WinUI 3 等,但窗口失去焦点时边框是半透明的,无法
|
||||
// 完美模拟。
|
||||
margins.cxLeftWidth = -1;
|
||||
//
|
||||
// 我们选择扩展到标题栏高度,这是最好的选择。一个自然的想法是,既然上边框只有一个像素高,我们扩展一
|
||||
// 个像素即可,可惜因为 DWM 的 bug,这会使窗口失去焦点时上边框变为透明。那么能否传一个负值,让边框
|
||||
// 扩展到整个客户区?这大部分情况下可以工作,有一个小 bug:不显示边框颜色的设置下深色模式的边框会变
|
||||
// 为纯黑而不是半透明。
|
||||
RECT frame{};
|
||||
AdjustWindowRectExForDpi(&frame, GetWindowStyle(_hWnd), FALSE, 0, _currentDpi);
|
||||
margins.cyTopHeight = -frame.top;
|
||||
}
|
||||
DwmExtendFrameIntoClientArea(_hWnd, &margins);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@
|
|||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<!-- Release 下不允许编译警告 -->
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!-- Conan 依赖 -->
|
||||
<ImportGroup Label="PropertySheets">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue