fix: initial dark mode title bar on Windows 10 (#39287)

This commit is contained in:
David Sanders 2023-07-31 22:02:23 -07:00 committed by GitHub
parent cfc0826b65
commit b2c62d6ad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 11 deletions

View file

@ -8,6 +8,7 @@
#include "electron/buildflags/buildflags.h"
#include "shell/browser/ui/views/win_frame_view.h"
#include "shell/browser/win/dark_mode.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/win/hwnd_metrics.h"
#include "ui/base/win/shell.h"
@ -37,6 +38,14 @@ bool ElectronDesktopWindowTreeHostWin::PreHandleMSG(UINT message,
return native_window_view_->PreHandleMSG(message, w_param, l_param, result);
}
bool ElectronDesktopWindowTreeHostWin::ShouldPaintAsActive() const {
if (force_should_paint_as_active_.has_value()) {
return force_should_paint_as_active_.value();
}
return views::DesktopWindowTreeHostWin::ShouldPaintAsActive();
}
bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels(
gfx::Insets* insets) const {
// Set DWMFrameInsets to prevent maximized frameless window from bleeding
@ -102,7 +111,26 @@ bool ElectronDesktopWindowTreeHostWin::HandleMouseEventForCaption(
void ElectronDesktopWindowTreeHostWin::OnNativeThemeUpdated(
ui::NativeTheme* observed_theme) {
win::SetDarkModeForWindow(GetAcceleratedWidget());
HWND hWnd = GetAcceleratedWidget();
win::SetDarkModeForWindow(hWnd);
auto* os_info = base::win::OSInfo::GetInstance();
auto const version = os_info->version();
// Toggle the nonclient area active state to force a redraw (Win10 workaround)
if (version < base::win::Version::WIN11) {
// When handling WM_NCACTIVATE messages, Chromium logical ORs the wParam and
// the value of ShouldPaintAsActive() - so if the latter is true, it's not
// possible to toggle the title bar to inactive. Force it to false while we
// send the message so that the wParam value will always take effect. Refs
// https://source.chromium.org/chromium/chromium/src/+/main:ui/views/win/hwnd_message_handler.cc;l=2332-2381;drc=e6361d070be0adc585ebbff89fec76e2df4ad768
force_should_paint_as_active_ = false;
::SendMessage(hWnd, WM_NCACTIVATE, hWnd != ::GetActiveWindow(), 0);
// Clear forced value and tell Chromium the value changed to get a repaint
force_should_paint_as_active_.reset();
PaintAsActiveChanged();
}
}
} // namespace electron

View file

@ -8,6 +8,7 @@
#include <windows.h>
#include "shell/browser/native_window_views.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
namespace electron {
@ -31,6 +32,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
WPARAM w_param,
LPARAM l_param,
LRESULT* result) override;
bool ShouldPaintAsActive() const override;
bool GetDwmFrameInsetsInPixels(gfx::Insets* insets) const override;
bool GetClientAreaInsets(gfx::Insets* insets,
HMONITOR monitor) const override;
@ -41,6 +43,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
private:
raw_ptr<NativeWindowViews> native_window_view_; // weak ref
absl::optional<bool> force_should_paint_as_active_;
};
} // namespace electron

View file

@ -25,16 +25,6 @@ HRESULT TrySetWindowTheme(HWND hWnd, bool dark) {
if (FAILED(result))
return result;
auto* os_info = base::win::OSInfo::GetInstance();
auto const version = os_info->version();
// Toggle the nonclient area active state to force a redraw (Win10 workaround)
if (version < base::win::Version::WIN11) {
HWND activeWindow = GetActiveWindow();
SendMessage(hWnd, WM_NCACTIVATE, hWnd != activeWindow, 0);
SendMessage(hWnd, WM_NCACTIVATE, hWnd == activeWindow, 0);
}
return S_OK;
}