-
Notifications
You must be signed in to change notification settings - Fork 15k
/
electron_desktop_window_tree_host_win.cc
123 lines (109 loc) · 5.21 KB
/
electron_desktop_window_tree_host_win.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/ui/win/electron_desktop_window_tree_host_win.h"
#include "base/win/windows_version.h"
#include "electron/buildflags/buildflags.h"
#include "shell/browser/ui/views/win_frame_view.h"
#include "ui/base/win/hwnd_metrics.h"
#include "ui/base/win/shell.h"
#if BUILDFLAG(ENABLE_WIN_DARK_MODE_WINDOW_UI)
#include "shell/browser/win/dark_mode.h"
#endif
namespace electron {
ElectronDesktopWindowTreeHostWin::ElectronDesktopWindowTreeHostWin(
NativeWindowViews* native_window_view,
views::DesktopNativeWidgetAura* desktop_native_widget_aura)
: views::DesktopWindowTreeHostWin(native_window_view->widget(),
desktop_native_widget_aura),
native_window_view_(native_window_view) {}
ElectronDesktopWindowTreeHostWin::~ElectronDesktopWindowTreeHostWin() = default;
bool ElectronDesktopWindowTreeHostWin::PreHandleMSG(UINT message,
WPARAM w_param,
LPARAM l_param,
LRESULT* result) {
#if BUILDFLAG(ENABLE_WIN_DARK_MODE_WINDOW_UI)
if (message == WM_NCCREATE) {
HWND const hwnd = GetAcceleratedWidget();
auto const theme_source =
ui::NativeTheme::GetInstanceForNativeUi()->theme_source();
win::SetDarkModeForWindow(hwnd, theme_source);
}
#endif
return native_window_view_->PreHandleMSG(message, w_param, l_param, result);
}
bool ElectronDesktopWindowTreeHostWin::ShouldPaintAsActive() const {
// Tell Chromium to use system default behavior when rendering inactive
// titlebar, otherwise it would render inactive titlebar as active under
// some cases.
// See also https://github.com/electron/electron/issues/24647.
return false;
}
bool ElectronDesktopWindowTreeHostWin::HasNativeFrame() const {
// Since we never use chromium's titlebar implementation, we can just say
// that we use a native titlebar. This will disable the repaint locking when
// DWM composition is disabled.
// See also https://github.com/electron/electron/issues/1821.
return !ui::win::IsAeroGlassEnabled();
}
bool ElectronDesktopWindowTreeHostWin::GetDwmFrameInsetsInPixels(
gfx::Insets* insets) const {
// Set DWMFrameInsets to prevent maximized frameless window from bleeding
// into other monitors.
if (IsMaximized() && !native_window_view_->has_frame()) {
// This would be equivalent to calling:
// DwmExtendFrameIntoClientArea({0, 0, 0, 0});
//
// which means do not extend window frame into client area. It is almost
// a no-op, but it can tell Windows to not extend the window frame to be
// larger than current workspace.
//
// See also:
// https://devblogs.microsoft.com/oldnewthing/20150304-00/?p=44543
*insets = gfx::Insets();
return true;
}
return false;
}
bool ElectronDesktopWindowTreeHostWin::GetClientAreaInsets(
gfx::Insets* insets,
HMONITOR monitor) const {
// Windows by deafult extends the maximized window slightly larger than
// current workspace, for frameless window since the standard frame has been
// removed, the client area would then be drew outside current workspace.
//
// Indenting the client area can fix this behavior.
if (IsMaximized() && !native_window_view_->has_frame()) {
// The insets would be eventually passed to WM_NCCALCSIZE, which takes
// the metrics under the DPI of _main_ monitor instead of current moniotr.
//
// Please make sure you tested maximized frameless window under multiple
// monitors with different DPIs before changing this code.
const int thickness = ::GetSystemMetrics(SM_CXSIZEFRAME) +
::GetSystemMetrics(SM_CXPADDEDBORDER);
insets->Set(thickness, thickness, thickness, thickness);
return true;
}
return false;
}
bool ElectronDesktopWindowTreeHostWin::HandleMouseEventForCaption(
UINT message) const {
// Windows does not seem to generate WM_NCPOINTERDOWN/UP touch events for
// caption buttons with WCO. This results in a no-op for
// HWNDMessageHandler::HandlePointerEventTypeTouchOrNonClient and
// WM_SYSCOMMAND is not generated for the touch action. However, Windows will
// also generate a mouse event for every touch action and this gets handled in
// HWNDMessageHandler::HandleMouseEventInternal.
// With https://chromium-review.googlesource.com/c/chromium/src/+/1048877/
// Chromium lets the OS handle caption buttons for FrameMode::SYSTEM_DRAWN but
// again this does not generate the SC_MINIMIZE, SC_MAXIMIZE, SC_RESTORE
// commands when Non-client mouse events are generated for HTCLOSE,
// HTMINBUTTON, HTMAXBUTTON. To workaround this issue, wit this delegate we
// let chromium handle the mouse events via
// HWNDMessageHandler::HandleMouseInputForCaption instead of the OS and this
// will generate the necessary system commands to perform caption button
// actions due to the DefWindowProc call.
// https://source.chromium.org/chromium/chromium/src/+/main:ui/views/win/hwnd_message_handler.cc;l=3611
return native_window_view_->IsWindowControlsOverlayEnabled();
}
} // namespace electron