OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/widget/native_widget_win.h" | 5 #include "views/widget/native_widget_win.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 #include <shellapi.h> |
8 | 9 |
9 #include "base/string_util.h" | 10 #include "base/string_util.h" |
10 #include "base/system_monitor/system_monitor.h" | 11 #include "base/system_monitor/system_monitor.h" |
| 12 #include "base/win/scoped_gdi_object.h" |
| 13 #include "base/win/win_util.h" |
11 #include "base/win/windows_version.h" | 14 #include "base/win/windows_version.h" |
12 #include "ui/base/dragdrop/drag_drop_types.h" | 15 #include "ui/base/dragdrop/drag_drop_types.h" |
13 #include "ui/base/dragdrop/drag_source.h" | 16 #include "ui/base/dragdrop/drag_source.h" |
14 #include "ui/base/dragdrop/os_exchange_data.h" | 17 #include "ui/base/dragdrop/os_exchange_data.h" |
15 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 18 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
16 #include "ui/base/keycodes/keyboard_code_conversion_win.h" | 19 #include "ui/base/keycodes/keyboard_code_conversion_win.h" |
17 #include "ui/base/l10n/l10n_util_win.h" | 20 #include "ui/base/l10n/l10n_util_win.h" |
18 #include "ui/base/theme_provider.h" | 21 #include "ui/base/theme_provider.h" |
19 #include "ui/base/view_prop.h" | 22 #include "ui/base/view_prop.h" |
20 #include "ui/base/win/hwnd_util.h" | 23 #include "ui/base/win/hwnd_util.h" |
21 #include "ui/gfx/canvas_skia.h" | 24 #include "ui/gfx/canvas_skia.h" |
| 25 #include "ui/gfx/canvas_skia_paint.h" |
22 #include "ui/gfx/icon_util.h" | 26 #include "ui/gfx/icon_util.h" |
23 #include "ui/gfx/native_theme_win.h" | 27 #include "ui/gfx/native_theme_win.h" |
24 #include "ui/gfx/path.h" | 28 #include "ui/gfx/path.h" |
25 #include "views/accessibility/native_view_accessibility_win.h" | 29 #include "views/accessibility/native_view_accessibility_win.h" |
26 #include "views/controls/native_control_win.h" | 30 #include "views/controls/native_control_win.h" |
27 #include "views/controls/textfield/native_textfield_views.h" | 31 #include "views/controls/textfield/native_textfield_views.h" |
28 #include "views/focus/accelerator_handler.h" | 32 #include "views/focus/accelerator_handler.h" |
29 #include "views/focus/focus_util_win.h" | 33 #include "views/focus/focus_util_win.h" |
30 #include "views/focus/view_storage.h" | 34 #include "views/focus/view_storage.h" |
31 #include "views/ime/input_method_win.h" | 35 #include "views/ime/input_method_win.h" |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) { | 196 BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) { |
193 DWORD process_id; | 197 DWORD process_id; |
194 GetWindowThreadProcessId(hwnd, &process_id); | 198 GetWindowThreadProcessId(hwnd, &process_id); |
195 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME; | 199 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME; |
196 if (process_id == GetCurrentProcessId()) | 200 if (process_id == GetCurrentProcessId()) |
197 flags |= RDW_UPDATENOW; | 201 flags |= RDW_UPDATENOW; |
198 RedrawWindow(hwnd, NULL, NULL, flags); | 202 RedrawWindow(hwnd, NULL, NULL, flags); |
199 return TRUE; | 203 return TRUE; |
200 } | 204 } |
201 | 205 |
| 206 // See comments in OnNCPaint() for details of this struct. |
| 207 struct ClipState { |
| 208 // The window being painted. |
| 209 HWND parent; |
| 210 |
| 211 // DC painting to. |
| 212 HDC dc; |
| 213 |
| 214 // Origin of the window in terms of the screen. |
| 215 int x; |
| 216 int y; |
| 217 }; |
| 218 |
| 219 // See comments in OnNCPaint() for details of this function. |
| 220 static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) { |
| 221 ClipState* clip_state = reinterpret_cast<ClipState*>(param); |
| 222 if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) { |
| 223 RECT bounds; |
| 224 GetWindowRect(window, &bounds); |
| 225 ExcludeClipRect(clip_state->dc, |
| 226 bounds.left - clip_state->x, |
| 227 bounds.top - clip_state->y, |
| 228 bounds.right - clip_state->x, |
| 229 bounds.bottom - clip_state->y); |
| 230 } |
| 231 return TRUE; |
| 232 } |
| 233 |
| 234 // The thickness of an auto-hide taskbar in pixels. |
| 235 static const int kAutoHideTaskbarThicknessPx = 2; |
| 236 |
| 237 bool GetMonitorAndRects(const RECT& rect, |
| 238 HMONITOR* monitor, |
| 239 gfx::Rect* monitor_rect, |
| 240 gfx::Rect* work_area) { |
| 241 DCHECK(monitor); |
| 242 DCHECK(monitor_rect); |
| 243 DCHECK(work_area); |
| 244 *monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL); |
| 245 if (!*monitor) |
| 246 return false; |
| 247 MONITORINFO monitor_info = { 0 }; |
| 248 monitor_info.cbSize = sizeof(monitor_info); |
| 249 GetMonitorInfo(*monitor, &monitor_info); |
| 250 *monitor_rect = monitor_info.rcMonitor; |
| 251 *work_area = monitor_info.rcWork; |
| 252 return true; |
| 253 } |
| 254 |
| 255 // Returns true if edge |edge| (one of ABE_LEFT, TOP, RIGHT, or BOTTOM) of |
| 256 // monitor |monitor| has an auto-hiding taskbar that's always-on-top. |
| 257 bool EdgeHasTopmostAutoHideTaskbar(UINT edge, HMONITOR monitor) { |
| 258 APPBARDATA taskbar_data = { 0 }; |
| 259 taskbar_data.cbSize = sizeof APPBARDATA; |
| 260 taskbar_data.uEdge = edge; |
| 261 HWND taskbar = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, |
| 262 &taskbar_data)); |
| 263 return ::IsWindow(taskbar) && (monitor != NULL) && |
| 264 (MonitorFromWindow(taskbar, MONITOR_DEFAULTTONULL) == monitor) && |
| 265 (GetWindowLong(taskbar, GWL_EXSTYLE) & WS_EX_TOPMOST); |
| 266 } |
| 267 |
202 // Links the HWND to its NativeWidget. | 268 // Links the HWND to its NativeWidget. |
203 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; | 269 const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__"; |
204 | 270 |
205 // A custom MSAA object id used to determine if a screen reader is actively | 271 // A custom MSAA object id used to determine if a screen reader is actively |
206 // listening for MSAA events. | 272 // listening for MSAA events. |
207 const int kCustomObjectID = 1; | 273 const int kCustomObjectID = 1; |
208 | 274 |
209 // If the hung renderer warning doesn't fit on screen, the amount of padding to | 275 // If the hung renderer warning doesn't fit on screen, the amount of padding to |
210 // be left between the edge of the window and the edge of the nearest monitor, | 276 // be left between the edge of the window and the edge of the nearest monitor, |
211 // after the window is nudged back on screen. Pixels. | 277 // after the window is nudged back on screen. Pixels. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 can_update_layered_window_(true), | 339 can_update_layered_window_(true), |
274 focus_on_creation_(true), | 340 focus_on_creation_(true), |
275 restore_focus_when_enabled_(false), | 341 restore_focus_when_enabled_(false), |
276 accessibility_view_events_index_(-1), | 342 accessibility_view_events_index_(-1), |
277 accessibility_view_events_(kMaxAccessibilityViewEvents), | 343 accessibility_view_events_(kMaxAccessibilityViewEvents), |
278 previous_cursor_(NULL), | 344 previous_cursor_(NULL), |
279 is_input_method_win_(false), | 345 is_input_method_win_(false), |
280 fullscreen_(false), | 346 fullscreen_(false), |
281 force_hidden_count_(0), | 347 force_hidden_count_(0), |
282 lock_updates_(false), | 348 lock_updates_(false), |
283 saved_window_style_(0) { | 349 saved_window_style_(0), |
| 350 ignore_window_pos_changes_(false), |
| 351 ignore_pos_changes_factory_(this), |
| 352 last_monitor_(NULL), |
| 353 is_right_mouse_pressed_on_caption_(false), |
| 354 restored_enabled_(false) { |
284 } | 355 } |
285 | 356 |
286 NativeWidgetWin::~NativeWidgetWin() { | 357 NativeWidgetWin::~NativeWidgetWin() { |
287 // We need to delete the input method before calling DestroyRootView(), | 358 // We need to delete the input method before calling DestroyRootView(), |
288 // because it'll set focus_manager_ to NULL. | 359 // because it'll set focus_manager_ to NULL. |
289 input_method_.reset(); | 360 input_method_.reset(); |
290 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) | 361 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) |
291 delete delegate_; | 362 delete delegate_; |
292 } | 363 } |
293 | 364 |
294 // static | 365 // static |
295 bool NativeWidgetWin::IsAeroGlassEnabled() { | 366 bool NativeWidgetWin::IsAeroGlassEnabled() { |
296 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 367 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
297 return false; | 368 return false; |
298 // If composition is not enabled, we behave like on XP. | 369 // If composition is not enabled, we behave like on XP. |
299 BOOL enabled = FALSE; | 370 BOOL enabled = FALSE; |
300 return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled; | 371 return SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled; |
301 } | 372 } |
302 | 373 |
| 374 // static |
| 375 gfx::Font NativeWidgetWin::GetWindowTitleFont() { |
| 376 NONCLIENTMETRICS ncm; |
| 377 base::win::GetNonClientMetrics(&ncm); |
| 378 l10n_util::AdjustUIFont(&(ncm.lfCaptionFont)); |
| 379 base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont))); |
| 380 return gfx::Font(caption_font); |
| 381 } |
| 382 |
303 void NativeWidgetWin::Show(int show_state) { | 383 void NativeWidgetWin::Show(int show_state) { |
304 ShowWindow(show_state); | 384 ShowWindow(show_state); |
305 // When launched from certain programs like bash and Windows Live Messenger, | 385 // When launched from certain programs like bash and Windows Live Messenger, |
306 // show_state is set to SW_HIDE, so we need to correct that condition. We | 386 // show_state is set to SW_HIDE, so we need to correct that condition. We |
307 // don't just change show_state to SW_SHOWNORMAL because MSDN says we must | 387 // don't just change show_state to SW_SHOWNORMAL because MSDN says we must |
308 // always first call ShowWindow with the specified value from STARTUPINFO, | 388 // always first call ShowWindow with the specified value from STARTUPINFO, |
309 // otherwise all future ShowWindow calls will be ignored (!!#@@#!). Instead, | 389 // otherwise all future ShowWindow calls will be ignored (!!#@@#!). Instead, |
310 // we call ShowWindow again in this case. | 390 // we call ShowWindow again in this case. |
311 if (show_state == SW_HIDE) { | 391 if (show_state == SW_HIDE) { |
312 show_state = SW_SHOWNORMAL; | 392 show_state = SW_SHOWNORMAL; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 ShowWindow(SW_SHOW); | 439 ShowWindow(SW_SHOW); |
360 } | 440 } |
361 } | 441 } |
362 | 442 |
363 //////////////////////////////////////////////////////////////////////////////// | 443 //////////////////////////////////////////////////////////////////////////////// |
364 // NativeWidgetWin, NativeWidget implementation: | 444 // NativeWidgetWin, NativeWidget implementation: |
365 | 445 |
366 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) { | 446 void NativeWidgetWin::InitNativeWidget(const Widget::InitParams& params) { |
367 SetInitParams(params); | 447 SetInitParams(params); |
368 | 448 |
| 449 GetMonitorAndRects(params.bounds.ToRECT(), &last_monitor_, |
| 450 &last_monitor_rect_, &last_work_area_); |
| 451 |
369 // Create the window. | 452 // Create the window. |
370 gfx::NativeView parent = params.parent_widget ? | 453 gfx::NativeView parent = params.parent_widget ? |
371 params.parent_widget->GetNativeView() : params.parent; | 454 params.parent_widget->GetNativeView() : params.parent; |
372 WindowImpl::Init(parent, params.bounds); | 455 WindowImpl::Init(parent, params.bounds); |
373 } | 456 } |
374 | 457 |
375 NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() { | 458 NonClientFrameView* NativeWidgetWin::CreateNonClientFrameView() { |
376 return GetWidget()->ShouldUseNativeFrame() ? | 459 return GetWidget()->ShouldUseNativeFrame() ? |
377 new NativeFrameView(GetWidget()) : NULL; | 460 new NativeFrameView(GetWidget()) : NULL; |
378 } | 461 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 if (SUCCEEDED(hr)) { | 693 if (SUCCEEDED(hr)) { |
611 VARIANT var; | 694 VARIANT var; |
612 if (state) { | 695 if (state) { |
613 var.lVal = NativeViewAccessibilityWin::MSAAState(state); | 696 var.lVal = NativeViewAccessibilityWin::MSAAState(state); |
614 hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, | 697 hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, |
615 CHILDID_SELF, PROPID_ACC_STATE, var); | 698 CHILDID_SELF, PROPID_ACC_STATE, var); |
616 } | 699 } |
617 } | 700 } |
618 } | 701 } |
619 | 702 |
| 703 void NativeWidgetWin::BecomeModal() { |
| 704 // We implement modality by crawling up the hierarchy of windows starting |
| 705 // at the owner, disabling all of them so that they don't receive input |
| 706 // messages. |
| 707 HWND start = ::GetWindow(GetNativeView(), GW_OWNER); |
| 708 while (start) { |
| 709 ::EnableWindow(start, FALSE); |
| 710 start = ::GetParent(start); |
| 711 } |
| 712 } |
| 713 |
620 gfx::Rect NativeWidgetWin::GetWindowScreenBounds() const { | 714 gfx::Rect NativeWidgetWin::GetWindowScreenBounds() const { |
621 RECT r; | 715 RECT r; |
622 GetWindowRect(&r); | 716 GetWindowRect(&r); |
623 return gfx::Rect(r); | 717 return gfx::Rect(r); |
624 } | 718 } |
625 | 719 |
626 gfx::Rect NativeWidgetWin::GetClientAreaScreenBounds() const { | 720 gfx::Rect NativeWidgetWin::GetClientAreaScreenBounds() const { |
627 RECT r; | 721 RECT r; |
628 GetClientRect(&r); | 722 GetClientRect(&r); |
629 POINT point = { r.left, r.top }; | 723 POINT point = { r.left, r.top }; |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 | 1170 |
1077 // Bug 964884: detach the IME attached to this window. | 1171 // Bug 964884: detach the IME attached to this window. |
1078 // We should attach IMEs only when we need to input CJK strings. | 1172 // We should attach IMEs only when we need to input CJK strings. |
1079 ImmAssociateContextEx(hwnd(), NULL, 0); | 1173 ImmAssociateContextEx(hwnd(), NULL, 0); |
1080 | 1174 |
1081 // We need to allow the delegate to size its contents since the window may not | 1175 // We need to allow the delegate to size its contents since the window may not |
1082 // receive a size notification when its initial bounds are specified at window | 1176 // receive a size notification when its initial bounds are specified at window |
1083 // creation time. | 1177 // creation time. |
1084 ClientAreaSizeChanged(); | 1178 ClientAreaSizeChanged(); |
1085 | 1179 |
1086 delegate_->OnNativeWidgetCreated(); | 1180 delegate_->OnNativeWidgetCreated(gfx::Rect(create_struct->x, |
| 1181 create_struct->y, |
| 1182 create_struct->cx, |
| 1183 create_struct->cy)); |
1087 | 1184 |
1088 // delegate_->OnNativeWidgetCreated() creates the focus manager for top-level | 1185 // delegate_->OnNativeWidgetCreated() creates the focus manager for top-level |
1089 // widget. Only top-level widget should have an input method. | 1186 // widget. Only top-level widget should have an input method. |
1090 if (delegate_->HasFocusManager() && | 1187 if (delegate_->HasFocusManager() && |
1091 NativeTextfieldViews::IsTextfieldViewsEnabled()) { | 1188 NativeTextfieldViews::IsTextfieldViewsEnabled()) { |
1092 input_method_.reset(new InputMethodWin(this)); | 1189 input_method_.reset(new InputMethodWin(this)); |
1093 input_method_->Init(GetWidget()); | 1190 input_method_->Init(GetWidget()); |
1094 is_input_method_win_ = true; | 1191 is_input_method_win_ = true; |
1095 } | 1192 } |
1096 return 0; | 1193 return 0; |
1097 } | 1194 } |
1098 | 1195 |
1099 void NativeWidgetWin::OnDestroy() { | 1196 void NativeWidgetWin::OnDestroy() { |
| 1197 RestoreEnabledIfNecessary(); |
1100 delegate_->OnNativeWidgetDestroying(); | 1198 delegate_->OnNativeWidgetDestroying(); |
1101 if (drop_target_.get()) { | 1199 if (drop_target_.get()) { |
1102 RevokeDragDrop(hwnd()); | 1200 RevokeDragDrop(hwnd()); |
1103 drop_target_ = NULL; | 1201 drop_target_ = NULL; |
1104 } | 1202 } |
1105 | 1203 |
1106 props_.reset(); | 1204 props_.reset(); |
1107 } | 1205 } |
1108 | 1206 |
1109 void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) { | 1207 void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) { |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; | 1400 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; |
1303 if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE) | 1401 if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE) |
1304 return MA_NOACTIVATE; | 1402 return MA_NOACTIVATE; |
1305 SetMsgHandled(FALSE); | 1403 SetMsgHandled(FALSE); |
1306 return MA_ACTIVATE; | 1404 return MA_ACTIVATE; |
1307 } | 1405 } |
1308 | 1406 |
1309 LRESULT NativeWidgetWin::OnMouseRange(UINT message, | 1407 LRESULT NativeWidgetWin::OnMouseRange(UINT message, |
1310 WPARAM w_param, | 1408 WPARAM w_param, |
1311 LPARAM l_param) { | 1409 LPARAM l_param) { |
| 1410 if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) { |
| 1411 is_right_mouse_pressed_on_caption_ = false; |
| 1412 ReleaseCapture(); |
| 1413 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() |
| 1414 // expect screen coordinates. |
| 1415 CPoint screen_point(l_param); |
| 1416 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); |
| 1417 w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, |
| 1418 MAKELPARAM(screen_point.x, screen_point.y)); |
| 1419 if (w_param == HTCAPTION || w_param == HTSYSMENU) { |
| 1420 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; |
| 1421 if (base::i18n::IsRTL()) |
| 1422 flags |= TPM_RIGHTALIGN; |
| 1423 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); |
| 1424 int id = TrackPopupMenu(system_menu, flags, screen_point.x, |
| 1425 screen_point.y, 0, GetNativeView(), NULL); |
| 1426 ExecuteSystemMenuCommand(id); |
| 1427 return 0; |
| 1428 } |
| 1429 } else if (message == WM_NCLBUTTONDOWN && |
| 1430 !GetWidget()->ShouldUseNativeFrame()) { |
| 1431 switch (w_param) { |
| 1432 case HTCLOSE: |
| 1433 case HTMINBUTTON: |
| 1434 case HTMAXBUTTON: { |
| 1435 // When the mouse is pressed down in these specific non-client areas, |
| 1436 // we need to tell the RootView to send the mouse pressed event (which |
| 1437 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ |
| 1438 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be |
| 1439 // sent by the applicable button's ButtonListener. We _have_ to do this |
| 1440 // way rather than letting Windows just send the syscommand itself (as |
| 1441 // would happen if we never did this dance) because for some insane |
| 1442 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed |
| 1443 // window control button appearance, in the Windows classic style, over |
| 1444 // our view! Ick! By handling this message we prevent Windows from |
| 1445 // doing this undesirable thing, but that means we need to roll the |
| 1446 // sys-command handling ourselves. |
| 1447 // Combine |w_param| with common key state message flags. |
| 1448 w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; |
| 1449 w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; |
| 1450 } |
| 1451 } |
| 1452 } else if (message == WM_NCRBUTTONDOWN && |
| 1453 (w_param == HTCAPTION || w_param == HTSYSMENU)) { |
| 1454 is_right_mouse_pressed_on_caption_ = true; |
| 1455 // We SetMouseCapture() to ensure we only show the menu when the button |
| 1456 // down and up are both on the caption. Note: this causes the button up to |
| 1457 // be WM_RBUTTONUP instead of WM_NCRBUTTONUP. |
| 1458 SetMouseCapture(); |
| 1459 } |
| 1460 |
| 1461 /* |
| 1462 TODO(beng): This fixes some situations where the windows-classic appearance |
| 1463 non-client area is rendered over our custom frame, however it |
| 1464 causes mouse-releases to the non-client area to be eaten, so it |
| 1465 can't be enabled. |
| 1466 if (message == WM_NCLBUTTONDOWN) { |
| 1467 // NativeWidgetWin::OnNCLButtonDown set the message as un-handled. This |
| 1468 // normally means NativeWidgetWin::ProcessWindowMessage will pass it to |
| 1469 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird |
| 1470 // non-client painting, so we need to call it directly here inside a |
| 1471 // scoped update lock. |
| 1472 ScopedRedrawLock lock(this); |
| 1473 NativeWidgetWin::OnMouseRange(message, w_param, l_param); |
| 1474 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); |
| 1475 SetMsgHandled(TRUE); |
| 1476 } |
| 1477 */ |
| 1478 |
1312 MSG msg = { hwnd(), message, w_param, l_param, 0, | 1479 MSG msg = { hwnd(), message, w_param, l_param, 0, |
1313 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; | 1480 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; |
1314 MouseEvent event(msg); | 1481 MouseEvent event(msg); |
1315 | 1482 |
1316 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) | 1483 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) |
1317 tooltip_manager_->OnMouse(message, w_param, l_param); | 1484 tooltip_manager_->OnMouse(message, w_param, l_param); |
1318 | 1485 |
1319 if (event.type() == ui::ET_MOUSE_MOVED && !HasMouseCapture()) { | 1486 if (event.type() == ui::ET_MOUSE_MOVED && !HasMouseCapture()) { |
1320 // Windows only fires WM_MOUSELEAVE events if the application begins | 1487 // Windows only fires WM_MOUSELEAVE events if the application begins |
1321 // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. | 1488 // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 | 1545 |
1379 // If we're active again, we should be allowed to render as inactive, so | 1546 // If we're active again, we should be allowed to render as inactive, so |
1380 // tell the non-client view. | 1547 // tell the non-client view. |
1381 bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled(); | 1548 bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled(); |
1382 if (IsActive()) | 1549 if (IsActive()) |
1383 delegate_->EnableInactiveRendering(); | 1550 delegate_->EnableInactiveRendering(); |
1384 | 1551 |
1385 return CallDefaultNCActivateHandler(inactive_rendering_disabled || active); | 1552 return CallDefaultNCActivateHandler(inactive_rendering_disabled || active); |
1386 } | 1553 } |
1387 | 1554 |
1388 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) { | 1555 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { |
1389 SetMsgHandled(FALSE); | 1556 // We only override the default handling if we need to specify a custom |
1390 return 0; | 1557 // non-client edge width. Note that in most cases "no insets" means no |
| 1558 // custom width, but in fullscreen mode we want a custom width of 0. |
| 1559 gfx::Insets insets = GetClientAreaInsets(); |
| 1560 if (insets.empty() && !IsFullscreen()) { |
| 1561 SetMsgHandled(FALSE); |
| 1562 return 0; |
| 1563 } |
| 1564 |
| 1565 RECT* client_rect = mode ? |
| 1566 &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : |
| 1567 reinterpret_cast<RECT*>(l_param); |
| 1568 client_rect->left += insets.left(); |
| 1569 client_rect->top += insets.top(); |
| 1570 client_rect->bottom -= insets.bottom(); |
| 1571 client_rect->right -= insets.right(); |
| 1572 if (IsMaximized()) { |
| 1573 // Find all auto-hide taskbars along the screen edges and adjust in by the |
| 1574 // thickness of the auto-hide taskbar on each such edge, so the window isn't |
| 1575 // treated as a "fullscreen app", which would cause the taskbars to |
| 1576 // disappear. |
| 1577 HMONITOR monitor = MonitorFromWindow(GetNativeView(), |
| 1578 MONITOR_DEFAULTTONULL); |
| 1579 if (!monitor) { |
| 1580 // We might end up here if the window was previously minimized and the |
| 1581 // user clicks on the taskbar button to restore it in the previously |
| 1582 // maximized position. In that case WM_NCCALCSIZE is sent before the |
| 1583 // window coordinates are restored to their previous values, so our |
| 1584 // (left,top) would probably be (-32000,-32000) like all minimized |
| 1585 // windows. So the above MonitorFromWindow call fails, but if we check |
| 1586 // the window rect given with WM_NCCALCSIZE (which is our previous |
| 1587 // restored window position) we will get the correct monitor handle. |
| 1588 monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL); |
| 1589 if (!monitor) { |
| 1590 // This is probably an extreme case that we won't hit, but if we don't |
| 1591 // intersect any monitor, let us not adjust the client rect since our |
| 1592 // window will not be visible anyway. |
| 1593 return 0; |
| 1594 } |
| 1595 } |
| 1596 if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) |
| 1597 client_rect->left += kAutoHideTaskbarThicknessPx; |
| 1598 if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { |
| 1599 if (GetWidget()->ShouldUseNativeFrame()) { |
| 1600 // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of |
| 1601 // WM_NCHITTEST, having any nonclient area atop the window causes the |
| 1602 // caption buttons to draw onscreen but not respond to mouse |
| 1603 // hover/clicks. |
| 1604 // So for a taskbar at the screen top, we can't push the |
| 1605 // client_rect->top down; instead, we move the bottom up by one pixel, |
| 1606 // which is the smallest change we can make and still get a client area |
| 1607 // less than the screen size. This is visibly ugly, but there seems to |
| 1608 // be no better solution. |
| 1609 --client_rect->bottom; |
| 1610 } else { |
| 1611 client_rect->top += kAutoHideTaskbarThicknessPx; |
| 1612 } |
| 1613 } |
| 1614 if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) |
| 1615 client_rect->right -= kAutoHideTaskbarThicknessPx; |
| 1616 if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) |
| 1617 client_rect->bottom -= kAutoHideTaskbarThicknessPx; |
| 1618 |
| 1619 // We cannot return WVR_REDRAW when there is nonclient area, or Windows |
| 1620 // exhibits bugs where client pixels and child HWNDs are mispositioned by |
| 1621 // the width/height of the upper-left nonclient area. |
| 1622 return 0; |
| 1623 } |
| 1624 |
| 1625 // If the window bounds change, we're going to relayout and repaint anyway. |
| 1626 // Returning WVR_REDRAW avoids an extra paint before that of the old client |
| 1627 // pixels in the (now wrong) location, and thus makes actions like resizing a |
| 1628 // window from the left edge look slightly less broken. |
| 1629 // We special case when left or top insets are 0, since these conditions |
| 1630 // actually require another repaint to correct the layout after glass gets |
| 1631 // turned on and off. |
| 1632 if (insets.left() == 0 || insets.top() == 0) |
| 1633 return 0; |
| 1634 return mode ? WVR_REDRAW : 0; |
1391 } | 1635 } |
1392 | 1636 |
1393 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) { | 1637 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) { |
1394 if (!GetWidget()->non_client_view()) { | 1638 if (!GetWidget()->non_client_view()) { |
1395 SetMsgHandled(FALSE); | 1639 SetMsgHandled(FALSE); |
1396 return 0; | 1640 return 0; |
1397 } | 1641 } |
1398 | 1642 |
1399 // If the DWM is rendering the window controls, we need to give the DWM's | 1643 // If the DWM is rendering the window controls, we need to give the DWM's |
1400 // default window procedure first chance to handle hit testing. | 1644 // default window procedure first chance to handle hit testing. |
(...skipping 13 matching lines...) Expand all Loading... |
1414 if (component != HTNOWHERE) | 1658 if (component != HTNOWHERE) |
1415 return component; | 1659 return component; |
1416 | 1660 |
1417 // Otherwise, we let Windows do all the native frame non-client handling for | 1661 // Otherwise, we let Windows do all the native frame non-client handling for |
1418 // us. | 1662 // us. |
1419 SetMsgHandled(FALSE); | 1663 SetMsgHandled(FALSE); |
1420 return 0; | 1664 return 0; |
1421 } | 1665 } |
1422 | 1666 |
1423 void NativeWidgetWin::OnNCPaint(HRGN rgn) { | 1667 void NativeWidgetWin::OnNCPaint(HRGN rgn) { |
1424 SetMsgHandled(FALSE); | 1668 // We only do non-client painting if we're not using the native frame. |
| 1669 // It's required to avoid some native painting artifacts from appearing when |
| 1670 // the window is resized. |
| 1671 if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) { |
| 1672 SetMsgHandled(FALSE); |
| 1673 return; |
| 1674 } |
| 1675 |
| 1676 // We have an NC region and need to paint it. We expand the NC region to |
| 1677 // include the dirty region of the root view. This is done to minimize |
| 1678 // paints. |
| 1679 CRect window_rect; |
| 1680 GetWindowRect(&window_rect); |
| 1681 |
| 1682 if (window_rect.Width() != GetWidget()->GetRootView()->width() || |
| 1683 window_rect.Height() != GetWidget()->GetRootView()->height()) { |
| 1684 // If the size of the window differs from the size of the root view it |
| 1685 // means we're being asked to paint before we've gotten a WM_SIZE. This can |
| 1686 // happen when the user is interactively resizing the window. To avoid |
| 1687 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll |
| 1688 // reset the region of the window which triggers another WM_NCPAINT and |
| 1689 // all is well. |
| 1690 return; |
| 1691 } |
| 1692 |
| 1693 CRect dirty_region; |
| 1694 // A value of 1 indicates paint all. |
| 1695 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { |
| 1696 dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); |
| 1697 } else { |
| 1698 RECT rgn_bounding_box; |
| 1699 GetRgnBox(rgn, &rgn_bounding_box); |
| 1700 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) |
| 1701 return; // Dirty region doesn't intersect window bounds, bale. |
| 1702 |
| 1703 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. |
| 1704 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); |
| 1705 } |
| 1706 |
| 1707 // In theory GetDCEx should do what we want, but I couldn't get it to work. |
| 1708 // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell |
| 1709 // it doesn't work at all. So, instead we get the DC for the window then |
| 1710 // manually clip out the children. |
| 1711 HDC dc = GetWindowDC(GetNativeView()); |
| 1712 ClipState clip_state; |
| 1713 clip_state.x = window_rect.left; |
| 1714 clip_state.y = window_rect.top; |
| 1715 clip_state.parent = GetNativeView(); |
| 1716 clip_state.dc = dc; |
| 1717 EnumChildWindows(GetNativeView(), &ClipDCToChild, |
| 1718 reinterpret_cast<LPARAM>(&clip_state)); |
| 1719 |
| 1720 gfx::Rect old_paint_region = invalid_rect(); |
| 1721 |
| 1722 if (!old_paint_region.IsEmpty()) { |
| 1723 // The root view has a region that needs to be painted. Include it in the |
| 1724 // region we're going to paint. |
| 1725 |
| 1726 CRect old_paint_region_crect = old_paint_region.ToRECT(); |
| 1727 CRect tmp = dirty_region; |
| 1728 UnionRect(&dirty_region, &tmp, &old_paint_region_crect); |
| 1729 } |
| 1730 |
| 1731 GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region)); |
| 1732 |
| 1733 // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap |
| 1734 // the following in a block to force paint to occur so that we can release |
| 1735 // the dc. |
| 1736 { |
| 1737 gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left, |
| 1738 dirty_region.top, dirty_region.Width(), |
| 1739 dirty_region.Height()); |
| 1740 delegate_->OnNativeWidgetPaint(&canvas); |
| 1741 } |
| 1742 |
| 1743 ReleaseDC(GetNativeView(), dc); |
| 1744 // When using a custom frame, we want to avoid calling DefWindowProc() since |
| 1745 // that may render artifacts. |
| 1746 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); |
1425 } | 1747 } |
1426 | 1748 |
1427 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg, | 1749 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg, |
1428 WPARAM w_param, | 1750 WPARAM w_param, |
1429 LPARAM l_param) { | 1751 LPARAM l_param) { |
1430 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | 1752 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for |
1431 // an explanation about why we need to handle this message. | 1753 // an explanation about why we need to handle this message. |
1432 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); | 1754 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); |
1433 return 0; | 1755 return 0; |
1434 } | 1756 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 gfx::NativeThemeWin::instance()->CloseHandles(); | 1915 gfx::NativeThemeWin::instance()->CloseHandles(); |
1594 } | 1916 } |
1595 | 1917 |
1596 void NativeWidgetWin::OnVScroll(int scroll_type, | 1918 void NativeWidgetWin::OnVScroll(int scroll_type, |
1597 short position, | 1919 short position, |
1598 HWND scrollbar) { | 1920 HWND scrollbar) { |
1599 SetMsgHandled(FALSE); | 1921 SetMsgHandled(FALSE); |
1600 } | 1922 } |
1601 | 1923 |
1602 void NativeWidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) { | 1924 void NativeWidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| 1925 if (ignore_window_pos_changes_) { |
| 1926 // If somebody's trying to toggle our visibility, change the nonclient area, |
| 1927 // change our Z-order, or activate us, we should probably let it go through. |
| 1928 if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | |
| 1929 SWP_FRAMECHANGED)) && |
| 1930 (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { |
| 1931 // Just sizing/moving the window; ignore. |
| 1932 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; |
| 1933 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); |
| 1934 } |
| 1935 } else if (!GetParent()) { |
| 1936 CRect window_rect; |
| 1937 HMONITOR monitor; |
| 1938 gfx::Rect monitor_rect, work_area; |
| 1939 if (GetWindowRect(&window_rect) && |
| 1940 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 1941 if (monitor && (monitor == last_monitor_) && |
| 1942 (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && |
| 1943 (work_area != last_work_area_)))) { |
| 1944 // A rect for the monitor we're on changed. Normally Windows notifies |
| 1945 // us about this (and thus we're reaching here due to the SetWindowPos() |
| 1946 // call in OnSettingChange() above), but with some software (e.g. |
| 1947 // nVidia's nView desktop manager) the work area can change asynchronous |
| 1948 // to any notification, and we're just sent a SetWindowPos() call with a |
| 1949 // new (frequently incorrect) position/size. In either case, the best |
| 1950 // response is to throw away the existing position/size information in |
| 1951 // |window_pos| and recalculate it based on the new work rect. |
| 1952 gfx::Rect new_window_rect; |
| 1953 if (IsFullscreen()) { |
| 1954 new_window_rect = monitor_rect; |
| 1955 } else if (IsZoomed()) { |
| 1956 new_window_rect = work_area; |
| 1957 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
| 1958 new_window_rect.Inset(-border_thickness, -border_thickness); |
| 1959 } else { |
| 1960 new_window_rect = gfx::Rect(window_rect).AdjustToFit(work_area); |
| 1961 } |
| 1962 window_pos->x = new_window_rect.x(); |
| 1963 window_pos->y = new_window_rect.y(); |
| 1964 window_pos->cx = new_window_rect.width(); |
| 1965 window_pos->cy = new_window_rect.height(); |
| 1966 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child |
| 1967 // HWNDs for some reason. |
| 1968 window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); |
| 1969 window_pos->flags |= SWP_NOCOPYBITS; |
| 1970 |
| 1971 // Now ignore all immediately-following SetWindowPos() changes. Windows |
| 1972 // likes to (incorrectly) recalculate what our position/size should be |
| 1973 // and send us further updates. |
| 1974 ignore_window_pos_changes_ = true; |
| 1975 DCHECK(ignore_pos_changes_factory_.empty()); |
| 1976 MessageLoop::current()->PostTask(FROM_HERE, |
| 1977 ignore_pos_changes_factory_.NewRunnableMethod( |
| 1978 &NativeWidgetWin::StopIgnoringPosChanges)); |
| 1979 } |
| 1980 last_monitor_ = monitor; |
| 1981 last_monitor_rect_ = monitor_rect; |
| 1982 last_work_area_ = work_area; |
| 1983 } |
| 1984 } |
| 1985 |
1603 if (force_hidden_count_) { | 1986 if (force_hidden_count_) { |
1604 // Prevent the window from being made visible if we've been asked to do so. | 1987 // Prevent the window from being made visible if we've been asked to do so. |
1605 // See comment in header as to why we might want this. | 1988 // See comment in header as to why we might want this. |
1606 window_pos->flags &= ~SWP_SHOWWINDOW; | 1989 window_pos->flags &= ~SWP_SHOWWINDOW; |
1607 } | 1990 } |
1608 | 1991 |
1609 SetMsgHandled(FALSE); | 1992 SetMsgHandled(FALSE); |
1610 } | 1993 } |
1611 | 1994 |
1612 void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) { | 1995 void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) { |
(...skipping 11 matching lines...) Expand all Loading... |
1624 //////////////////////////////////////////////////////////////////////////////// | 2007 //////////////////////////////////////////////////////////////////////////////// |
1625 // NativeWidgetWin, protected: | 2008 // NativeWidgetWin, protected: |
1626 | 2009 |
1627 int NativeWidgetWin::GetShowState() const { | 2010 int NativeWidgetWin::GetShowState() const { |
1628 return SW_SHOWNORMAL; | 2011 return SW_SHOWNORMAL; |
1629 } | 2012 } |
1630 | 2013 |
1631 gfx::Insets NativeWidgetWin::GetClientAreaInsets() const { | 2014 gfx::Insets NativeWidgetWin::GetClientAreaInsets() const { |
1632 // Returning an empty Insets object causes the default handling in | 2015 // Returning an empty Insets object causes the default handling in |
1633 // NativeWidgetWin::OnNCCalcSize() to be invoked. | 2016 // NativeWidgetWin::OnNCCalcSize() to be invoked. |
1634 if (GetWidget()->ShouldUseNativeFrame()) | 2017 if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) |
1635 return gfx::Insets(); | 2018 return gfx::Insets(); |
1636 | 2019 |
1637 if (IsMaximized()) { | 2020 if (IsMaximized()) { |
1638 // Windows automatically adds a standard width border to all sides when a | 2021 // Windows automatically adds a standard width border to all sides when a |
1639 // window is maximized. | 2022 // window is maximized. |
1640 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | 2023 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
1641 return gfx::Insets(border_thickness, border_thickness, border_thickness, | 2024 return gfx::Insets(border_thickness, border_thickness, border_thickness, |
1642 border_thickness); | 2025 border_thickness); |
1643 } | 2026 } |
1644 // This is weird, but highly essential. If we don't offset the bottom edge | 2027 // This is weird, but highly essential. If we don't offset the bottom edge |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1773 ex_style |= l10n_util::GetExtendedTooltipStyles(); | 2156 ex_style |= l10n_util::GetExtendedTooltipStyles(); |
1774 if (params.transparent) | 2157 if (params.transparent) |
1775 ex_style |= WS_EX_LAYERED; | 2158 ex_style |= WS_EX_LAYERED; |
1776 if (params.has_dropshadow) { | 2159 if (params.has_dropshadow) { |
1777 class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? | 2160 class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? |
1778 0 : CS_DROPSHADOW; | 2161 0 : CS_DROPSHADOW; |
1779 } | 2162 } |
1780 | 2163 |
1781 // Set type-dependent style attributes. | 2164 // Set type-dependent style attributes. |
1782 switch (params.type) { | 2165 switch (params.type) { |
1783 case Widget::InitParams::TYPE_WINDOW: | 2166 case Widget::InitParams::TYPE_WINDOW: { |
| 2167 style |= WS_SYSMENU | WS_CAPTION; |
| 2168 bool can_resize = GetWidget()->widget_delegate()->CanResize(); |
| 2169 bool can_maximize = GetWidget()->widget_delegate()->CanMaximize(); |
| 2170 if (can_maximize) { |
| 2171 style |= WS_OVERLAPPEDWINDOW; |
| 2172 } else if (can_resize) { |
| 2173 style |= WS_OVERLAPPED | WS_THICKFRAME; |
| 2174 } |
| 2175 if (delegate_->IsDialogBox()) { |
| 2176 style |= DS_MODALFRAME; |
| 2177 // NOTE: Turning this off means we lose the close button, which is bad. |
| 2178 // Turning it on though means the user can maximize or size the window |
| 2179 // from the system menu, which is worse. We may need to provide our own |
| 2180 // menu to get the close button to appear properly. |
| 2181 // style &= ~WS_SYSMENU; |
| 2182 } |
| 2183 ex_style |= delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; |
| 2184 break; |
| 2185 } |
1784 case Widget::InitParams::TYPE_CONTROL: | 2186 case Widget::InitParams::TYPE_CONTROL: |
1785 break; | 2187 break; |
1786 case Widget::InitParams::TYPE_POPUP: | 2188 case Widget::InitParams::TYPE_POPUP: |
1787 style |= WS_POPUP; | 2189 style |= WS_POPUP; |
1788 ex_style |= WS_EX_TOOLWINDOW; | 2190 ex_style |= WS_EX_TOOLWINDOW; |
1789 break; | 2191 break; |
1790 case Widget::InitParams::TYPE_MENU: | 2192 case Widget::InitParams::TYPE_MENU: |
1791 style |= WS_POPUP; | 2193 style |= WS_POPUP; |
1792 break; | 2194 break; |
1793 default: | 2195 default: |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 } | 2316 } |
1915 | 2317 |
1916 gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() { | 2318 gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() { |
1917 #if defined(VIEWS_COMPOSITOR) | 2319 #if defined(VIEWS_COMPOSITOR) |
1918 return hwnd(); | 2320 return hwnd(); |
1919 #else | 2321 #else |
1920 return gfx::kNullAcceleratedWidget; | 2322 return gfx::kNullAcceleratedWidget; |
1921 #endif | 2323 #endif |
1922 } | 2324 } |
1923 | 2325 |
| 2326 void NativeWidgetWin::RestoreEnabledIfNecessary() { |
| 2327 if (delegate_->IsModal() && !restored_enabled_) { |
| 2328 restored_enabled_ = true; |
| 2329 // If we were run modally, we need to undo the disabled-ness we inflicted on |
| 2330 // the owner's parent hierarchy. |
| 2331 HWND start = ::GetWindow(GetNativeView(), GW_OWNER); |
| 2332 while (start) { |
| 2333 ::EnableWindow(start, TRUE); |
| 2334 start = ::GetParent(start); |
| 2335 } |
| 2336 } |
| 2337 } |
| 2338 |
| 2339 |
1924 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { | 2340 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { |
1925 SetMsgHandled(delegate_->OnKeyEvent(key)); | 2341 SetMsgHandled(delegate_->OnKeyEvent(key)); |
1926 } | 2342 } |
1927 | 2343 |
1928 //////////////////////////////////////////////////////////////////////////////// | 2344 //////////////////////////////////////////////////////////////////////////////// |
1929 // Widget, public: | 2345 // Widget, public: |
1930 | 2346 |
1931 // static | 2347 // static |
1932 void Widget::NotifyLocaleChanged() { | 2348 void Widget::NotifyLocaleChanged() { |
1933 NOTIMPLEMENTED(); | 2349 NOTIMPLEMENTED(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 | 2480 |
2065 // And now, notify them that they have a brand new parent. | 2481 // And now, notify them that they have a brand new parent. |
2066 for (NativeWidgets::iterator it = widgets.begin(); | 2482 for (NativeWidgets::iterator it = widgets.begin(); |
2067 it != widgets.end(); ++it) { | 2483 it != widgets.end(); ++it) { |
2068 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, | 2484 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, |
2069 new_parent); | 2485 new_parent); |
2070 } | 2486 } |
2071 } | 2487 } |
2072 | 2488 |
2073 } // namespace views | 2489 } // namespace views |
OLD | NEW |