Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / ui / views / widget / widget_hwnd_utils.cc
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
3 // found in the LICENSE file.
4
5 #include "ui/views/widget/widget_hwnd_utils.h"
6
7 #include <dwmapi.h>
8
9 #include "base/command_line.h"
10 #include "base/win/windows_version.h"
11 #include "ui/base/l10n/l10n_util_win.h"
12 #include "ui/base/ui_base_switches.h"
13 #include "ui/views/widget/widget_delegate.h"
14 #include "ui/views/win/hwnd_message_handler.h"
15
16 #if defined(OS_WIN)
17 #include "ui/base/win/shell.h"
18 #endif
19
20 namespace views {
21
22 namespace {
23
24 void CalculateWindowStylesFromInitParams(
25     const Widget::InitParams& params,
26     WidgetDelegate* widget_delegate,
27     internal::NativeWidgetDelegate* native_widget_delegate,
28     DWORD* style,
29     DWORD* ex_style,
30     DWORD* class_style) {
31   *style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
32   *ex_style = 0;
33   *class_style = CS_DBLCLKS;
34
35   // Set type-independent style attributes.
36   if (params.child)
37     *style |= WS_CHILD;
38   if (params.show_state == ui::SHOW_STATE_MAXIMIZED)
39     *style |= WS_MAXIMIZE;
40   if (params.show_state == ui::SHOW_STATE_MINIMIZED)
41     *style |= WS_MINIMIZE;
42   if (!params.accept_events)
43     *ex_style |= WS_EX_TRANSPARENT;
44   if (!params.can_activate)
45     *ex_style |= WS_EX_NOACTIVATE;
46   if (params.keep_on_top)
47     *ex_style |= WS_EX_TOPMOST;
48   if (params.mirror_origin_in_rtl)
49     *ex_style |= l10n_util::GetExtendedTooltipStyles();
50   // Layered windows do not work with Aura. They are basically incompatible
51   // with Direct3D surfaces. Officially, it should be impossible to achieve
52   // per-pixel alpha compositing with the desktop and 3D acceleration but it
53   // has been discovered that since Vista There is a secret handshake between
54   // user32 and the DMW. If things are set up just right DMW gets out of the
55   // way; it does not create a backbuffer and simply blends our D3D surface
56   // and the desktop background. The handshake is as follows:
57   // 1- Use D3D9Ex to create device/swapchain, etc. You need D3DFMT_A8R8G8B8.
58   // 2- The window must have WS_EX_COMPOSITED in the extended style.
59   // 3- The window must have WS_POPUP in its style.
60   // 4- The windows must not have WM_SIZEBOX, WS_THICKFRAME or WS_CAPTION in its
61   //    style.
62   // 5- When the window is created but before it is presented, call
63   //    DwmExtendFrameIntoClientArea passing -1 as the margins.
64   if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) {
65     if (ui::win::IsAeroGlassEnabled())
66       *ex_style |= WS_EX_COMPOSITED;
67   }
68   if (params.has_dropshadow) {
69     *class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ?
70         0 : CS_DROPSHADOW;
71   }
72
73   // Set type-dependent style attributes.
74   switch (params.type) {
75     case Widget::InitParams::TYPE_PANEL:
76       *ex_style |= WS_EX_TOPMOST;
77       if (params.remove_standard_frame) {
78         *style |= WS_POPUP;
79         break;
80       }
81       // Else, no break. Fall through to TYPE_WINDOW.
82     case Widget::InitParams::TYPE_WINDOW: {
83       *style |= WS_SYSMENU | WS_CAPTION;
84       bool can_resize = widget_delegate->CanResize();
85       bool can_maximize = widget_delegate->CanMaximize();
86       if (can_maximize) {
87         *style |= WS_OVERLAPPEDWINDOW;
88       } else if (can_resize || params.remove_standard_frame) {
89         *style |= WS_OVERLAPPED | WS_THICKFRAME;
90       }
91       if (native_widget_delegate->IsDialogBox()) {
92         *style |= DS_MODALFRAME;
93         // NOTE: Turning this off means we lose the close button, which is bad.
94         // Turning it on though means the user can maximize or size the window
95         // from the system menu, which is worse. We may need to provide our own
96         // menu to get the close button to appear properly.
97         // style &= ~WS_SYSMENU;
98
99         // Set the WS_POPUP style for modal dialogs. This ensures that the owner
100         // window is activated on destruction. This style should not be set for
101         // non-modal non-top-level dialogs like constrained windows.
102         *style |= native_widget_delegate->IsModal() ? WS_POPUP : 0;
103       }
104       *ex_style |=
105           native_widget_delegate->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0;
106
107       // See layered window comment above.
108       if (*ex_style & WS_EX_COMPOSITED)
109         *style &= ~(WS_THICKFRAME | WS_CAPTION);
110       break;
111     }
112     case Widget::InitParams::TYPE_CONTROL:
113       *style |= WS_VISIBLE;
114       break;
115     case Widget::InitParams::TYPE_WINDOW_FRAMELESS:
116       *style |= WS_POPUP;
117       break;
118     case Widget::InitParams::TYPE_BUBBLE:
119       *style |= WS_POPUP;
120       *style |= WS_CLIPCHILDREN;
121       if (!params.force_show_in_taskbar)
122         *ex_style |= WS_EX_TOOLWINDOW;
123       break;
124     case Widget::InitParams::TYPE_POPUP:
125       *style |= WS_POPUP;
126       if (!params.force_show_in_taskbar)
127         *ex_style |= WS_EX_TOOLWINDOW;
128       break;
129     case Widget::InitParams::TYPE_MENU:
130       *style |= WS_POPUP;
131       break;
132     default:
133       NOTREACHED();
134   }
135 }
136
137 }  // namespace
138
139 bool DidClientAreaSizeChange(const WINDOWPOS* window_pos) {
140   return !(window_pos->flags & SWP_NOSIZE) ||
141          window_pos->flags & SWP_FRAMECHANGED;
142 }
143
144 void ConfigureWindowStyles(
145     HWNDMessageHandler* handler,
146     const Widget::InitParams& params,
147     WidgetDelegate* widget_delegate,
148     internal::NativeWidgetDelegate* native_widget_delegate) {
149   // Configure the HWNDMessageHandler with the appropriate
150   DWORD style = 0;
151   DWORD ex_style = 0;
152   DWORD class_style = 0;
153   CalculateWindowStylesFromInitParams(params, widget_delegate,
154                                       native_widget_delegate, &style, &ex_style,
155                                       &class_style);
156   handler->set_initial_class_style(class_style);
157   handler->set_window_style(handler->window_style() | style);
158   handler->set_window_ex_style(handler->window_ex_style() | ex_style);
159 }
160
161 }  // namespace views