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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 if (delegate_->HasFocusManager() && | 1184 if (delegate_->HasFocusManager() && |
1091 NativeTextfieldViews::IsTextfieldViewsEnabled()) { | 1185 NativeTextfieldViews::IsTextfieldViewsEnabled()) { |
1092 input_method_.reset(new InputMethodWin(this)); | 1186 input_method_.reset(new InputMethodWin(this)); |
1093 input_method_->Init(GetWidget()); | 1187 input_method_->Init(GetWidget()); |
1094 is_input_method_win_ = true; | 1188 is_input_method_win_ = true; |
1095 } | 1189 } |
1096 return 0; | 1190 return 0; |
1097 } | 1191 } |
1098 | 1192 |
1099 void NativeWidgetWin::OnDestroy() { | 1193 void NativeWidgetWin::OnDestroy() { |
| 1194 RestoreEnabledIfNecessary(); |
1100 delegate_->OnNativeWidgetDestroying(); | 1195 delegate_->OnNativeWidgetDestroying(); |
1101 if (drop_target_.get()) { | 1196 if (drop_target_.get()) { |
1102 RevokeDragDrop(hwnd()); | 1197 RevokeDragDrop(hwnd()); |
1103 drop_target_ = NULL; | 1198 drop_target_ = NULL; |
1104 } | 1199 } |
1105 | 1200 |
1106 props_.reset(); | 1201 props_.reset(); |
1107 } | 1202 } |
1108 | 1203 |
1109 void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) { | 1204 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; | 1397 return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT; |
1303 if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE) | 1398 if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE) |
1304 return MA_NOACTIVATE; | 1399 return MA_NOACTIVATE; |
1305 SetMsgHandled(FALSE); | 1400 SetMsgHandled(FALSE); |
1306 return MA_ACTIVATE; | 1401 return MA_ACTIVATE; |
1307 } | 1402 } |
1308 | 1403 |
1309 LRESULT NativeWidgetWin::OnMouseRange(UINT message, | 1404 LRESULT NativeWidgetWin::OnMouseRange(UINT message, |
1310 WPARAM w_param, | 1405 WPARAM w_param, |
1311 LPARAM l_param) { | 1406 LPARAM l_param) { |
| 1407 if (message == WM_RBUTTONUP && is_right_mouse_pressed_on_caption_) { |
| 1408 is_right_mouse_pressed_on_caption_ = false; |
| 1409 ReleaseCapture(); |
| 1410 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() |
| 1411 // expect screen coordinates. |
| 1412 CPoint screen_point(l_param); |
| 1413 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); |
| 1414 w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, |
| 1415 MAKELPARAM(screen_point.x, screen_point.y)); |
| 1416 if (w_param == HTCAPTION || w_param == HTSYSMENU) { |
| 1417 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; |
| 1418 if (base::i18n::IsRTL()) |
| 1419 flags |= TPM_RIGHTALIGN; |
| 1420 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); |
| 1421 int id = TrackPopupMenu(system_menu, flags, screen_point.x, |
| 1422 screen_point.y, 0, GetNativeView(), NULL); |
| 1423 ExecuteSystemMenuCommand(id); |
| 1424 return 0; |
| 1425 } |
| 1426 } else if (message == WM_NCLBUTTONDOWN && |
| 1427 !GetWidget()->ShouldUseNativeFrame()) { |
| 1428 switch (w_param) { |
| 1429 case HTCLOSE: |
| 1430 case HTMINBUTTON: |
| 1431 case HTMAXBUTTON: { |
| 1432 // When the mouse is pressed down in these specific non-client areas, |
| 1433 // we need to tell the RootView to send the mouse pressed event (which |
| 1434 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ |
| 1435 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be |
| 1436 // sent by the applicable button's ButtonListener. We _have_ to do this |
| 1437 // way rather than letting Windows just send the syscommand itself (as |
| 1438 // would happen if we never did this dance) because for some insane |
| 1439 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed |
| 1440 // window control button appearance, in the Windows classic style, over |
| 1441 // our view! Ick! By handling this message we prevent Windows from |
| 1442 // doing this undesirable thing, but that means we need to roll the |
| 1443 // sys-command handling ourselves. |
| 1444 // Combine |w_param| with common key state message flags. |
| 1445 w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; |
| 1446 w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; |
| 1447 } |
| 1448 } |
| 1449 } else if (message == WM_NCRBUTTONDOWN && |
| 1450 (w_param == HTCAPTION || w_param == HTSYSMENU)) { |
| 1451 is_right_mouse_pressed_on_caption_ = true; |
| 1452 // We SetMouseCapture() to ensure we only show the menu when the button |
| 1453 // down and up are both on the caption. Note: this causes the button up to |
| 1454 // be WM_RBUTTONUP instead of WM_NCRBUTTONUP. |
| 1455 SetMouseCapture(); |
| 1456 } |
| 1457 |
| 1458 /* |
| 1459 TODO(beng): This fixes some situations where the windows-classic appearance |
| 1460 non-client area is rendered over our custom frame, however it |
| 1461 causes mouse-releases to the non-client area to be eaten, so it |
| 1462 can't be enabled. |
| 1463 if (message == WM_NCLBUTTONDOWN) { |
| 1464 // NativeWidgetWin::OnNCLButtonDown set the message as un-handled. This |
| 1465 // normally means NativeWidgetWin::ProcessWindowMessage will pass it to |
| 1466 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird |
| 1467 // non-client painting, so we need to call it directly here inside a |
| 1468 // scoped update lock. |
| 1469 ScopedRedrawLock lock(this); |
| 1470 NativeWidgetWin::OnMouseRange(message, w_param, l_param); |
| 1471 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); |
| 1472 SetMsgHandled(TRUE); |
| 1473 } |
| 1474 */ |
| 1475 |
1312 MSG msg = { hwnd(), message, w_param, l_param, 0, | 1476 MSG msg = { hwnd(), message, w_param, l_param, 0, |
1313 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; | 1477 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; |
1314 MouseEvent event(msg); | 1478 MouseEvent event(msg); |
1315 | 1479 |
1316 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) | 1480 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) |
1317 tooltip_manager_->OnMouse(message, w_param, l_param); | 1481 tooltip_manager_->OnMouse(message, w_param, l_param); |
1318 | 1482 |
1319 if (event.type() == ui::ET_MOUSE_MOVED && !HasMouseCapture()) { | 1483 if (event.type() == ui::ET_MOUSE_MOVED && !HasMouseCapture()) { |
1320 // Windows only fires WM_MOUSELEAVE events if the application begins | 1484 // Windows only fires WM_MOUSELEAVE events if the application begins |
1321 // "tracking" mouse events for a given HWND during WM_MOUSEMOVE events. | 1485 // "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 | 1542 |
1379 // If we're active again, we should be allowed to render as inactive, so | 1543 // If we're active again, we should be allowed to render as inactive, so |
1380 // tell the non-client view. | 1544 // tell the non-client view. |
1381 bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled(); | 1545 bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled(); |
1382 if (IsActive()) | 1546 if (IsActive()) |
1383 delegate_->EnableInactiveRendering(); | 1547 delegate_->EnableInactiveRendering(); |
1384 | 1548 |
1385 return CallDefaultNCActivateHandler(inactive_rendering_disabled || active); | 1549 return CallDefaultNCActivateHandler(inactive_rendering_disabled || active); |
1386 } | 1550 } |
1387 | 1551 |
1388 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL w_param, LPARAM l_param) { | 1552 LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) { |
1389 SetMsgHandled(FALSE); | 1553 // We only override the default handling if we need to specify a custom |
1390 return 0; | 1554 // non-client edge width. Note that in most cases "no insets" means no |
| 1555 // custom width, but in fullscreen mode we want a custom width of 0. |
| 1556 gfx::Insets insets = GetClientAreaInsets(); |
| 1557 if (insets.empty() && !IsFullscreen()) { |
| 1558 SetMsgHandled(FALSE); |
| 1559 return 0; |
| 1560 } |
| 1561 |
| 1562 RECT* client_rect = mode ? |
| 1563 &reinterpret_cast<NCCALCSIZE_PARAMS*>(l_param)->rgrc[0] : |
| 1564 reinterpret_cast<RECT*>(l_param); |
| 1565 client_rect->left += insets.left(); |
| 1566 client_rect->top += insets.top(); |
| 1567 client_rect->bottom -= insets.bottom(); |
| 1568 client_rect->right -= insets.right(); |
| 1569 if (IsMaximized()) { |
| 1570 // Find all auto-hide taskbars along the screen edges and adjust in by the |
| 1571 // thickness of the auto-hide taskbar on each such edge, so the window isn't |
| 1572 // treated as a "fullscreen app", which would cause the taskbars to |
| 1573 // disappear. |
| 1574 HMONITOR monitor = MonitorFromWindow(GetNativeView(), |
| 1575 MONITOR_DEFAULTTONULL); |
| 1576 if (!monitor) { |
| 1577 // We might end up here if the window was previously minimized and the |
| 1578 // user clicks on the taskbar button to restore it in the previously |
| 1579 // maximized position. In that case WM_NCCALCSIZE is sent before the |
| 1580 // window coordinates are restored to their previous values, so our |
| 1581 // (left,top) would probably be (-32000,-32000) like all minimized |
| 1582 // windows. So the above MonitorFromWindow call fails, but if we check |
| 1583 // the window rect given with WM_NCCALCSIZE (which is our previous |
| 1584 // restored window position) we will get the correct monitor handle. |
| 1585 monitor = MonitorFromRect(client_rect, MONITOR_DEFAULTTONULL); |
| 1586 if (!monitor) { |
| 1587 // This is probably an extreme case that we won't hit, but if we don't |
| 1588 // intersect any monitor, let us not adjust the client rect since our |
| 1589 // window will not be visible anyway. |
| 1590 return 0; |
| 1591 } |
| 1592 } |
| 1593 if (EdgeHasTopmostAutoHideTaskbar(ABE_LEFT, monitor)) |
| 1594 client_rect->left += kAutoHideTaskbarThicknessPx; |
| 1595 if (EdgeHasTopmostAutoHideTaskbar(ABE_TOP, monitor)) { |
| 1596 if (GetWidget()->ShouldUseNativeFrame()) { |
| 1597 // Tricky bit. Due to a bug in DwmDefWindowProc()'s handling of |
| 1598 // WM_NCHITTEST, having any nonclient area atop the window causes the |
| 1599 // caption buttons to draw onscreen but not respond to mouse |
| 1600 // hover/clicks. |
| 1601 // So for a taskbar at the screen top, we can't push the |
| 1602 // client_rect->top down; instead, we move the bottom up by one pixel, |
| 1603 // which is the smallest change we can make and still get a client area |
| 1604 // less than the screen size. This is visibly ugly, but there seems to |
| 1605 // be no better solution. |
| 1606 --client_rect->bottom; |
| 1607 } else { |
| 1608 client_rect->top += kAutoHideTaskbarThicknessPx; |
| 1609 } |
| 1610 } |
| 1611 if (EdgeHasTopmostAutoHideTaskbar(ABE_RIGHT, monitor)) |
| 1612 client_rect->right -= kAutoHideTaskbarThicknessPx; |
| 1613 if (EdgeHasTopmostAutoHideTaskbar(ABE_BOTTOM, monitor)) |
| 1614 client_rect->bottom -= kAutoHideTaskbarThicknessPx; |
| 1615 |
| 1616 // We cannot return WVR_REDRAW when there is nonclient area, or Windows |
| 1617 // exhibits bugs where client pixels and child HWNDs are mispositioned by |
| 1618 // the width/height of the upper-left nonclient area. |
| 1619 return 0; |
| 1620 } |
| 1621 |
| 1622 // If the window bounds change, we're going to relayout and repaint anyway. |
| 1623 // Returning WVR_REDRAW avoids an extra paint before that of the old client |
| 1624 // pixels in the (now wrong) location, and thus makes actions like resizing a |
| 1625 // window from the left edge look slightly less broken. |
| 1626 // We special case when left or top insets are 0, since these conditions |
| 1627 // actually require another repaint to correct the layout after glass gets |
| 1628 // turned on and off. |
| 1629 if (insets.left() == 0 || insets.top() == 0) |
| 1630 return 0; |
| 1631 return mode ? WVR_REDRAW : 0; |
1391 } | 1632 } |
1392 | 1633 |
1393 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) { | 1634 LRESULT NativeWidgetWin::OnNCHitTest(const CPoint& point) { |
1394 if (!GetWidget()->non_client_view()) { | 1635 if (!GetWidget()->non_client_view()) { |
1395 SetMsgHandled(FALSE); | 1636 SetMsgHandled(FALSE); |
1396 return 0; | 1637 return 0; |
1397 } | 1638 } |
1398 | 1639 |
1399 // If the DWM is rendering the window controls, we need to give the DWM's | 1640 // 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. | 1641 // default window procedure first chance to handle hit testing. |
(...skipping 13 matching lines...) Expand all Loading... |
1414 if (component != HTNOWHERE) | 1655 if (component != HTNOWHERE) |
1415 return component; | 1656 return component; |
1416 | 1657 |
1417 // Otherwise, we let Windows do all the native frame non-client handling for | 1658 // Otherwise, we let Windows do all the native frame non-client handling for |
1418 // us. | 1659 // us. |
1419 SetMsgHandled(FALSE); | 1660 SetMsgHandled(FALSE); |
1420 return 0; | 1661 return 0; |
1421 } | 1662 } |
1422 | 1663 |
1423 void NativeWidgetWin::OnNCPaint(HRGN rgn) { | 1664 void NativeWidgetWin::OnNCPaint(HRGN rgn) { |
1424 SetMsgHandled(FALSE); | 1665 // We only do non-client painting if we're not using the native frame. |
| 1666 // It's required to avoid some native painting artifacts from appearing when |
| 1667 // the window is resized. |
| 1668 if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) { |
| 1669 SetMsgHandled(FALSE); |
| 1670 return; |
| 1671 } |
| 1672 |
| 1673 // We have an NC region and need to paint it. We expand the NC region to |
| 1674 // include the dirty region of the root view. This is done to minimize |
| 1675 // paints. |
| 1676 CRect window_rect; |
| 1677 GetWindowRect(&window_rect); |
| 1678 |
| 1679 if (window_rect.Width() != GetWidget()->GetRootView()->width() || |
| 1680 window_rect.Height() != GetWidget()->GetRootView()->height()) { |
| 1681 // If the size of the window differs from the size of the root view it |
| 1682 // means we're being asked to paint before we've gotten a WM_SIZE. This can |
| 1683 // happen when the user is interactively resizing the window. To avoid |
| 1684 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll |
| 1685 // reset the region of the window which triggers another WM_NCPAINT and |
| 1686 // all is well. |
| 1687 return; |
| 1688 } |
| 1689 |
| 1690 CRect dirty_region; |
| 1691 // A value of 1 indicates paint all. |
| 1692 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { |
| 1693 dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height()); |
| 1694 } else { |
| 1695 RECT rgn_bounding_box; |
| 1696 GetRgnBox(rgn, &rgn_bounding_box); |
| 1697 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) |
| 1698 return; // Dirty region doesn't intersect window bounds, bale. |
| 1699 |
| 1700 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. |
| 1701 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); |
| 1702 } |
| 1703 |
| 1704 // In theory GetDCEx should do what we want, but I couldn't get it to work. |
| 1705 // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell |
| 1706 // it doesn't work at all. So, instead we get the DC for the window then |
| 1707 // manually clip out the children. |
| 1708 HDC dc = GetWindowDC(GetNativeView()); |
| 1709 ClipState clip_state; |
| 1710 clip_state.x = window_rect.left; |
| 1711 clip_state.y = window_rect.top; |
| 1712 clip_state.parent = GetNativeView(); |
| 1713 clip_state.dc = dc; |
| 1714 EnumChildWindows(GetNativeView(), &ClipDCToChild, |
| 1715 reinterpret_cast<LPARAM>(&clip_state)); |
| 1716 |
| 1717 gfx::Rect old_paint_region = invalid_rect(); |
| 1718 |
| 1719 if (!old_paint_region.IsEmpty()) { |
| 1720 // The root view has a region that needs to be painted. Include it in the |
| 1721 // region we're going to paint. |
| 1722 |
| 1723 CRect old_paint_region_crect = old_paint_region.ToRECT(); |
| 1724 CRect tmp = dirty_region; |
| 1725 UnionRect(&dirty_region, &tmp, &old_paint_region_crect); |
| 1726 } |
| 1727 |
| 1728 GetWidget()->GetRootView()->SchedulePaintInRect(gfx::Rect(dirty_region)); |
| 1729 |
| 1730 // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap |
| 1731 // the following in a block to force paint to occur so that we can release |
| 1732 // the dc. |
| 1733 { |
| 1734 gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left, |
| 1735 dirty_region.top, dirty_region.Width(), |
| 1736 dirty_region.Height()); |
| 1737 delegate_->OnNativeWidgetPaint(&canvas); |
| 1738 } |
| 1739 |
| 1740 ReleaseDC(GetNativeView(), dc); |
| 1741 // When using a custom frame, we want to avoid calling DefWindowProc() since |
| 1742 // that may render artifacts. |
| 1743 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); |
1425 } | 1744 } |
1426 | 1745 |
1427 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg, | 1746 LRESULT NativeWidgetWin::OnNCUAHDrawCaption(UINT msg, |
1428 WPARAM w_param, | 1747 WPARAM w_param, |
1429 LPARAM l_param) { | 1748 LPARAM l_param) { |
1430 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | 1749 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for |
1431 // an explanation about why we need to handle this message. | 1750 // an explanation about why we need to handle this message. |
1432 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); | 1751 SetMsgHandled(!GetWidget()->ShouldUseNativeFrame()); |
1433 return 0; | 1752 return 0; |
1434 } | 1753 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 gfx::NativeThemeWin::instance()->CloseHandles(); | 1912 gfx::NativeThemeWin::instance()->CloseHandles(); |
1594 } | 1913 } |
1595 | 1914 |
1596 void NativeWidgetWin::OnVScroll(int scroll_type, | 1915 void NativeWidgetWin::OnVScroll(int scroll_type, |
1597 short position, | 1916 short position, |
1598 HWND scrollbar) { | 1917 HWND scrollbar) { |
1599 SetMsgHandled(FALSE); | 1918 SetMsgHandled(FALSE); |
1600 } | 1919 } |
1601 | 1920 |
1602 void NativeWidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) { | 1921 void NativeWidgetWin::OnWindowPosChanging(WINDOWPOS* window_pos) { |
| 1922 if (ignore_window_pos_changes_) { |
| 1923 // If somebody's trying to toggle our visibility, change the nonclient area, |
| 1924 // change our Z-order, or activate us, we should probably let it go through. |
| 1925 if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | |
| 1926 SWP_FRAMECHANGED)) && |
| 1927 (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { |
| 1928 // Just sizing/moving the window; ignore. |
| 1929 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; |
| 1930 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); |
| 1931 } |
| 1932 } else if (!GetParent()) { |
| 1933 CRect window_rect; |
| 1934 HMONITOR monitor; |
| 1935 gfx::Rect monitor_rect, work_area; |
| 1936 if (GetWindowRect(&window_rect) && |
| 1937 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 1938 if (monitor && (monitor == last_monitor_) && |
| 1939 (IsFullscreen() || ((monitor_rect == last_monitor_rect_) && |
| 1940 (work_area != last_work_area_)))) { |
| 1941 // A rect for the monitor we're on changed. Normally Windows notifies |
| 1942 // us about this (and thus we're reaching here due to the SetWindowPos() |
| 1943 // call in OnSettingChange() above), but with some software (e.g. |
| 1944 // nVidia's nView desktop manager) the work area can change asynchronous |
| 1945 // to any notification, and we're just sent a SetWindowPos() call with a |
| 1946 // new (frequently incorrect) position/size. In either case, the best |
| 1947 // response is to throw away the existing position/size information in |
| 1948 // |window_pos| and recalculate it based on the new work rect. |
| 1949 gfx::Rect new_window_rect; |
| 1950 if (IsFullscreen()) { |
| 1951 new_window_rect = monitor_rect; |
| 1952 } else if (IsZoomed()) { |
| 1953 new_window_rect = work_area; |
| 1954 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
| 1955 new_window_rect.Inset(-border_thickness, -border_thickness); |
| 1956 } else { |
| 1957 new_window_rect = gfx::Rect(window_rect).AdjustToFit(work_area); |
| 1958 } |
| 1959 window_pos->x = new_window_rect.x(); |
| 1960 window_pos->y = new_window_rect.y(); |
| 1961 window_pos->cx = new_window_rect.width(); |
| 1962 window_pos->cy = new_window_rect.height(); |
| 1963 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child |
| 1964 // HWNDs for some reason. |
| 1965 window_pos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); |
| 1966 window_pos->flags |= SWP_NOCOPYBITS; |
| 1967 |
| 1968 // Now ignore all immediately-following SetWindowPos() changes. Windows |
| 1969 // likes to (incorrectly) recalculate what our position/size should be |
| 1970 // and send us further updates. |
| 1971 ignore_window_pos_changes_ = true; |
| 1972 DCHECK(ignore_pos_changes_factory_.empty()); |
| 1973 MessageLoop::current()->PostTask(FROM_HERE, |
| 1974 ignore_pos_changes_factory_.NewRunnableMethod( |
| 1975 &NativeWidgetWin::StopIgnoringPosChanges)); |
| 1976 } |
| 1977 last_monitor_ = monitor; |
| 1978 last_monitor_rect_ = monitor_rect; |
| 1979 last_work_area_ = work_area; |
| 1980 } |
| 1981 } |
| 1982 |
1603 if (force_hidden_count_) { | 1983 if (force_hidden_count_) { |
1604 // Prevent the window from being made visible if we've been asked to do so. | 1984 // 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. | 1985 // See comment in header as to why we might want this. |
1606 window_pos->flags &= ~SWP_SHOWWINDOW; | 1986 window_pos->flags &= ~SWP_SHOWWINDOW; |
1607 } | 1987 } |
1608 | 1988 |
1609 SetMsgHandled(FALSE); | 1989 SetMsgHandled(FALSE); |
1610 } | 1990 } |
1611 | 1991 |
1612 void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) { | 1992 void NativeWidgetWin::OnWindowPosChanged(WINDOWPOS* window_pos) { |
(...skipping 11 matching lines...) Expand all Loading... |
1624 //////////////////////////////////////////////////////////////////////////////// | 2004 //////////////////////////////////////////////////////////////////////////////// |
1625 // NativeWidgetWin, protected: | 2005 // NativeWidgetWin, protected: |
1626 | 2006 |
1627 int NativeWidgetWin::GetShowState() const { | 2007 int NativeWidgetWin::GetShowState() const { |
1628 return SW_SHOWNORMAL; | 2008 return SW_SHOWNORMAL; |
1629 } | 2009 } |
1630 | 2010 |
1631 gfx::Insets NativeWidgetWin::GetClientAreaInsets() const { | 2011 gfx::Insets NativeWidgetWin::GetClientAreaInsets() const { |
1632 // Returning an empty Insets object causes the default handling in | 2012 // Returning an empty Insets object causes the default handling in |
1633 // NativeWidgetWin::OnNCCalcSize() to be invoked. | 2013 // NativeWidgetWin::OnNCCalcSize() to be invoked. |
1634 if (GetWidget()->ShouldUseNativeFrame()) | 2014 if (!GetWidget()->non_client_view() || GetWidget()->ShouldUseNativeFrame()) |
1635 return gfx::Insets(); | 2015 return gfx::Insets(); |
1636 | 2016 |
1637 if (IsMaximized()) { | 2017 if (IsMaximized()) { |
1638 // Windows automatically adds a standard width border to all sides when a | 2018 // Windows automatically adds a standard width border to all sides when a |
1639 // window is maximized. | 2019 // window is maximized. |
1640 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | 2020 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); |
1641 return gfx::Insets(border_thickness, border_thickness, border_thickness, | 2021 return gfx::Insets(border_thickness, border_thickness, border_thickness, |
1642 border_thickness); | 2022 border_thickness); |
1643 } | 2023 } |
1644 // This is weird, but highly essential. If we don't offset the bottom edge | 2024 // 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(); | 2153 ex_style |= l10n_util::GetExtendedTooltipStyles(); |
1774 if (params.transparent) | 2154 if (params.transparent) |
1775 ex_style |= WS_EX_LAYERED; | 2155 ex_style |= WS_EX_LAYERED; |
1776 if (params.has_dropshadow) { | 2156 if (params.has_dropshadow) { |
1777 class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? | 2157 class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ? |
1778 0 : CS_DROPSHADOW; | 2158 0 : CS_DROPSHADOW; |
1779 } | 2159 } |
1780 | 2160 |
1781 // Set type-dependent style attributes. | 2161 // Set type-dependent style attributes. |
1782 switch (params.type) { | 2162 switch (params.type) { |
1783 case Widget::InitParams::TYPE_WINDOW: | 2163 case Widget::InitParams::TYPE_WINDOW: { |
| 2164 style |= WS_SYSMENU | WS_CAPTION; |
| 2165 bool can_resize = GetWidget()->widget_delegate()->CanResize(); |
| 2166 bool can_maximize = GetWidget()->widget_delegate()->CanMaximize(); |
| 2167 if (can_maximize) { |
| 2168 style |= WS_OVERLAPPEDWINDOW; |
| 2169 } else if (can_resize) { |
| 2170 style |= WS_OVERLAPPED | WS_THICKFRAME; |
| 2171 } |
| 2172 if (delegate_->IsDialogBox()) { |
| 2173 style |= DS_MODALFRAME; |
| 2174 // NOTE: Turning this off means we lose the close button, which is bad. |
| 2175 // Turning it on though means the user can maximize or size the window |
| 2176 // from the system menu, which is worse. We may need to provide our own |
| 2177 // menu to get the close button to appear properly. |
| 2178 // style &= ~WS_SYSMENU; |
| 2179 } |
| 2180 ex_style |= delegate_->IsDialogBox() ? WS_EX_DLGMODALFRAME : 0; |
| 2181 break; |
| 2182 } |
1784 case Widget::InitParams::TYPE_CONTROL: | 2183 case Widget::InitParams::TYPE_CONTROL: |
1785 break; | 2184 break; |
1786 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: | 2185 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: |
1787 style |= WS_POPUP; | 2186 style |= WS_POPUP; |
1788 break; | 2187 break; |
1789 case Widget::InitParams::TYPE_POPUP: | 2188 case Widget::InitParams::TYPE_POPUP: |
1790 style |= WS_POPUP; | 2189 style |= WS_POPUP; |
1791 ex_style |= WS_EX_TOOLWINDOW; | 2190 ex_style |= WS_EX_TOOLWINDOW; |
1792 break; | 2191 break; |
1793 case Widget::InitParams::TYPE_MENU: | 2192 case Widget::InitParams::TYPE_MENU: |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 } | 2316 } |
1918 | 2317 |
1919 gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() { | 2318 gfx::AcceleratedWidget NativeWidgetWin::GetAcceleratedWidget() { |
1920 #if defined(VIEWS_COMPOSITOR) | 2319 #if defined(VIEWS_COMPOSITOR) |
1921 return hwnd(); | 2320 return hwnd(); |
1922 #else | 2321 #else |
1923 return gfx::kNullAcceleratedWidget; | 2322 return gfx::kNullAcceleratedWidget; |
1924 #endif | 2323 #endif |
1925 } | 2324 } |
1926 | 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 |
1927 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { | 2340 void NativeWidgetWin::DispatchKeyEventPostIME(const KeyEvent& key) { |
1928 SetMsgHandled(delegate_->OnKeyEvent(key)); | 2341 SetMsgHandled(delegate_->OnKeyEvent(key)); |
1929 } | 2342 } |
1930 | 2343 |
1931 //////////////////////////////////////////////////////////////////////////////// | 2344 //////////////////////////////////////////////////////////////////////////////// |
1932 // Widget, public: | 2345 // Widget, public: |
1933 | 2346 |
1934 // static | 2347 // static |
1935 void Widget::NotifyLocaleChanged() { | 2348 void Widget::NotifyLocaleChanged() { |
1936 NOTIMPLEMENTED(); | 2349 NOTIMPLEMENTED(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 | 2480 |
2068 // And now, notify them that they have a brand new parent. | 2481 // And now, notify them that they have a brand new parent. |
2069 for (NativeWidgets::iterator it = widgets.begin(); | 2482 for (NativeWidgets::iterator it = widgets.begin(); |
2070 it != widgets.end(); ++it) { | 2483 it != widgets.end(); ++it) { |
2071 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, | 2484 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, |
2072 new_parent); | 2485 new_parent); |
2073 } | 2486 } |
2074 } | 2487 } |
2075 | 2488 |
2076 } // namespace views | 2489 } // namespace views |
OLD | NEW |