OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/widget/widget_hwnd_utils.h" | 5 #include "ui/views/widget/widget_hwnd_utils.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
11 #include "ui/base/l10n/l10n_util_win.h" | 11 #include "ui/base/l10n/l10n_util_win.h" |
12 #include "ui/base/ui_base_switches.h" | 12 #include "ui/base/ui_base_switches.h" |
13 #include "ui/views/widget/widget_delegate.h" | 13 #include "ui/views/widget/widget_delegate.h" |
14 #include "ui/views/win/hwnd_message_handler.h" | 14 #include "ui/views/win/hwnd_message_handler.h" |
15 | 15 |
16 #if defined(OS_WIN) | 16 #if defined(OS_WIN) |
17 #include "ui/base/win/shell.h" | 17 #include "ui/base/win/shell.h" |
18 #endif | 18 #endif |
19 | 19 |
20 namespace views { | 20 namespace views { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 void CalculateWindowStylesFromInitParams( | 24 void CalculateWindowStylesFromInitParams( |
25 const Widget::InitParams& params, | 25 const Widget::InitParams& params, |
26 WidgetDelegate* widget_delegate, | 26 WidgetDelegate* widget_delegate, |
27 internal::NativeWidgetDelegate* native_widget_delegate, | 27 internal::NativeWidgetDelegate* native_widget_delegate, |
28 bool is_composited, | |
28 DWORD* style, | 29 DWORD* style, |
29 DWORD* ex_style, | 30 DWORD* ex_style, |
30 DWORD* class_style) { | 31 DWORD* class_style) { |
31 *style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | 32 *style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; |
32 *ex_style = 0; | 33 *ex_style = 0; |
33 *class_style = CS_DBLCLKS; | 34 *class_style = CS_DBLCLKS; |
34 | 35 |
35 // Set type-independent style attributes. | 36 // Set type-independent style attributes. |
36 if (params.child) | 37 if (params.child) |
37 *style |= WS_CHILD; | 38 *style |= WS_CHILD; |
38 if (params.show_state == ui::SHOW_STATE_MAXIMIZED) | 39 if (params.show_state == ui::SHOW_STATE_MAXIMIZED) |
39 *style |= WS_MAXIMIZE; | 40 *style |= WS_MAXIMIZE; |
40 if (params.show_state == ui::SHOW_STATE_MINIMIZED) | 41 if (params.show_state == ui::SHOW_STATE_MINIMIZED) |
41 *style |= WS_MINIMIZE; | 42 *style |= WS_MINIMIZE; |
42 if (!params.accept_events) | 43 if (!params.accept_events) |
43 *ex_style |= WS_EX_TRANSPARENT; | 44 *ex_style |= WS_EX_TRANSPARENT; |
44 DCHECK_NE(Widget::InitParams::ACTIVATABLE_DEFAULT, params.activatable); | 45 DCHECK_NE(Widget::InitParams::ACTIVATABLE_DEFAULT, params.activatable); |
45 if (params.activatable == Widget::InitParams::ACTIVATABLE_NO) | 46 if (params.activatable == Widget::InitParams::ACTIVATABLE_NO) |
46 *ex_style |= WS_EX_NOACTIVATE; | 47 *ex_style |= WS_EX_NOACTIVATE; |
47 if (params.keep_on_top) | 48 if (params.keep_on_top) |
48 *ex_style |= WS_EX_TOPMOST; | 49 *ex_style |= WS_EX_TOPMOST; |
49 if (params.mirror_origin_in_rtl) | 50 if (params.mirror_origin_in_rtl) |
50 *ex_style |= l10n_util::GetExtendedTooltipStyles(); | 51 *ex_style |= l10n_util::GetExtendedTooltipStyles(); |
51 // Layered windows do not work with Aura. They are basically incompatible | |
52 // with Direct3D surfaces. Officially, it should be impossible to achieve | |
53 // per-pixel alpha compositing with the desktop and 3D acceleration but it | |
54 // has been discovered that since Vista There is a secret handshake between | |
55 // user32 and the DMW. If things are set up just right DMW gets out of the | |
56 // way; it does not create a backbuffer and simply blends our D3D surface | |
57 // and the desktop background. The handshake is as follows: | |
58 // 1- Use D3D9Ex to create device/swapchain, etc. You need D3DFMT_A8R8G8B8. | |
59 // 2- The window must have WS_EX_COMPOSITED in the extended style. | |
60 // 3- The window must have WS_POPUP in its style. | |
61 // 4- The windows must not have WM_SIZEBOX, WS_THICKFRAME or WS_CAPTION in its | |
62 // style. | |
63 // 5- When the window is created but before it is presented, call | |
64 // DwmExtendFrameIntoClientArea passing -1 as the margins. | |
65 // We also set the WS_EX_COMPOSITED style for software composited translucent | |
66 // windows, which ensures that they are updated via the layered window code | |
67 // path in the software compositor. | |
68 if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW && | |
69 (ui::win::IsAeroGlassEnabled() || params.force_software_compositing)) | |
70 *ex_style |= WS_EX_COMPOSITED; | |
71 | |
72 if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP) | 52 if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP) |
73 *class_style |= CS_DROPSHADOW; | 53 *class_style |= CS_DROPSHADOW; |
74 | 54 |
75 // Set type-dependent style attributes. | 55 // Set type-dependent style attributes. |
76 switch (params.type) { | 56 switch (params.type) { |
77 case Widget::InitParams::TYPE_PANEL: | 57 case Widget::InitParams::TYPE_PANEL: |
78 *ex_style |= WS_EX_TOPMOST; | 58 *ex_style |= WS_EX_TOPMOST; |
79 if (params.remove_standard_frame) { | 59 if (params.remove_standard_frame) { |
80 *style |= WS_POPUP; | 60 *style |= WS_POPUP; |
81 break; | 61 break; |
(...skipping 23 matching lines...) Expand all Loading... | |
105 | 85 |
106 // Set the WS_POPUP style for modal dialogs. This ensures that the owner | 86 // Set the WS_POPUP style for modal dialogs. This ensures that the owner |
107 // window is activated on destruction. This style should not be set for | 87 // window is activated on destruction. This style should not be set for |
108 // non-modal non-top-level dialogs like constrained windows. | 88 // non-modal non-top-level dialogs like constrained windows. |
109 *style |= native_widget_delegate->IsModal() ? WS_POPUP : 0; | 89 *style |= native_widget_delegate->IsModal() ? WS_POPUP : 0; |
110 } | 90 } |
111 *ex_style |= | 91 *ex_style |= |
112 native_widget_delegate->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; | 92 native_widget_delegate->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; |
113 | 93 |
114 // See layered window comment above. | 94 // See layered window comment above. |
115 if (*ex_style & WS_EX_COMPOSITED) | 95 if (is_composited) |
116 *style &= ~(WS_THICKFRAME | WS_CAPTION); | 96 *style &= ~(WS_THICKFRAME | WS_CAPTION); |
117 break; | 97 break; |
118 } | 98 } |
119 case Widget::InitParams::TYPE_CONTROL: | 99 case Widget::InitParams::TYPE_CONTROL: |
120 *style |= WS_VISIBLE; | 100 *style |= WS_VISIBLE; |
121 break; | 101 break; |
122 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: | 102 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: |
123 *style |= WS_POPUP; | 103 *style |= WS_POPUP; |
124 break; | 104 break; |
125 case Widget::InitParams::TYPE_BUBBLE: | 105 case Widget::InitParams::TYPE_BUBBLE: |
(...skipping 24 matching lines...) Expand all Loading... | |
150 | 130 |
151 void ConfigureWindowStyles( | 131 void ConfigureWindowStyles( |
152 HWNDMessageHandler* handler, | 132 HWNDMessageHandler* handler, |
153 const Widget::InitParams& params, | 133 const Widget::InitParams& params, |
154 WidgetDelegate* widget_delegate, | 134 WidgetDelegate* widget_delegate, |
155 internal::NativeWidgetDelegate* native_widget_delegate) { | 135 internal::NativeWidgetDelegate* native_widget_delegate) { |
156 // Configure the HWNDMessageHandler with the appropriate | 136 // Configure the HWNDMessageHandler with the appropriate |
157 DWORD style = 0; | 137 DWORD style = 0; |
158 DWORD ex_style = 0; | 138 DWORD ex_style = 0; |
159 DWORD class_style = 0; | 139 DWORD class_style = 0; |
140 // Layered windows do not work with Direct3D, so a different mechanism needs | |
141 // to be used to allow for transparent borderless windows. | |
142 // | |
143 // 1- To allow the contents of the swapchain to blend with the contents | |
144 // behind it, it must must be created with D3DFMT_A8R8G8B8 in D3D9Ex, or | |
145 // with DXGI_ALPHA_MODE_PREMULTIPLIED with DirectComposition. | |
146 // 2- When the window is created but before it is presented, call | |
147 // DwmExtendFrameIntoClientArea passing -1 as the margins so that | |
148 // it's blended with the content below the window and not just black. | |
149 // 3- To avoid having a window frame and to avoid blurring the contents | |
150 // behind the window, the window must have WS_POPUP in its style and must | |
151 // not have not have WM_SIZEBOX, WS_THICKFRAME or WS_CAPTION in its | |
152 // style. | |
153 // | |
154 // This doesn't work when Aero is disabled, so disable it in that case. | |
155 // Software composited windows can continue to use WS_EX_LAYERED. | |
156 bool is_translucent = | |
157 (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW && | |
158 (ui::win::IsAeroGlassEnabled() || params.force_software_compositing)); | |
sky
2017/04/20 17:26:28
What happens if IsAeroGlassEnabled() changes durin
| |
159 | |
160 CalculateWindowStylesFromInitParams(params, widget_delegate, | 160 CalculateWindowStylesFromInitParams(params, widget_delegate, |
161 native_widget_delegate, &style, &ex_style, | 161 native_widget_delegate, is_translucent, |
162 &class_style); | 162 &style, &ex_style, &class_style); |
163 handler->set_translucent(is_translucent); | |
163 handler->set_initial_class_style(class_style); | 164 handler->set_initial_class_style(class_style); |
164 handler->set_window_style(handler->window_style() | style); | 165 handler->set_window_style(handler->window_style() | style); |
165 handler->set_window_ex_style(handler->window_ex_style() | ex_style); | 166 handler->set_window_ex_style(handler->window_ex_style() | ex_style); |
166 } | 167 } |
167 | 168 |
168 } // namespace views | 169 } // namespace views |
OLD | NEW |