Chromium Code Reviews| 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 |