| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/views/window.h" | 5 #include "chrome/views/window.h" |
| 6 | 6 |
| 7 #include "base/win_util.h" | 7 #include "base/win_util.h" |
| 8 #include "chrome/app/chrome_dll_resource.h" | 8 #include "chrome/app/chrome_dll_resource.h" |
| 9 #include "chrome/common/gfx/chrome_font.h" | 9 #include "chrome/common/gfx/chrome_font.h" |
| 10 #include "chrome/common/gfx/icon_util.h" | 10 #include "chrome/common/gfx/icon_util.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 123 |
| 124 void Window::Close() { | 124 void Window::Close() { |
| 125 if (window_closed_) { | 125 if (window_closed_) { |
| 126 // It appears we can hit this code path if you close a modal dialog then | 126 // It appears we can hit this code path if you close a modal dialog then |
| 127 // close the last browser before the destructor is hit, which triggers | 127 // close the last browser before the destructor is hit, which triggers |
| 128 // invoking Close again. I'm short circuiting this code path to avoid | 128 // invoking Close again. I'm short circuiting this code path to avoid |
| 129 // calling into the delegate twice, which is problematic. | 129 // calling into the delegate twice, which is problematic. |
| 130 return; | 130 return; |
| 131 } | 131 } |
| 132 | 132 |
| 133 if (client_view_->CanClose()) { | 133 if (non_client_view_->CanClose()) { |
| 134 SaveWindowPosition(); | 134 SaveWindowPosition(); |
| 135 RestoreEnabledIfNecessary(); | 135 RestoreEnabledIfNecessary(); |
| 136 WidgetWin::Close(); | 136 WidgetWin::Close(); |
| 137 // If the user activates another app after opening us, then comes back and | 137 // If the user activates another app after opening us, then comes back and |
| 138 // closes us, we want our owner to gain activation. But only if the owner | 138 // closes us, we want our owner to gain activation. But only if the owner |
| 139 // is visible. If we don't manually force that here, the other app will | 139 // is visible. If we don't manually force that here, the other app will |
| 140 // regain activation instead. | 140 // regain activation instead. |
| 141 if (owning_hwnd_ && GetHWND() == GetForegroundWindow() && | 141 if (owning_hwnd_ && GetHWND() == GetForegroundWindow() && |
| 142 IsWindowVisible(owning_hwnd_)) { | 142 IsWindowVisible(owning_hwnd_)) { |
| 143 SetForegroundWindow(owning_hwnd_); | 143 SetForegroundWindow(owning_hwnd_); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 Close(); | 244 Close(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 /////////////////////////////////////////////////////////////////////////////// | 247 /////////////////////////////////////////////////////////////////////////////// |
| 248 // Window, protected: | 248 // Window, protected: |
| 249 | 249 |
| 250 Window::Window(WindowDelegate* window_delegate) | 250 Window::Window(WindowDelegate* window_delegate) |
| 251 : WidgetWin(), | 251 : WidgetWin(), |
| 252 focus_on_creation_(true), | 252 focus_on_creation_(true), |
| 253 window_delegate_(window_delegate), | 253 window_delegate_(window_delegate), |
| 254 non_client_view_(NULL), | 254 non_client_view_(new NonClientView), |
| 255 client_view_(NULL), | |
| 256 owning_hwnd_(NULL), | 255 owning_hwnd_(NULL), |
| 257 minimum_size_(100, 100), | 256 minimum_size_(100, 100), |
| 258 is_modal_(false), | 257 is_modal_(false), |
| 259 restored_enabled_(false), | 258 restored_enabled_(false), |
| 260 is_always_on_top_(false), | 259 is_always_on_top_(false), |
| 261 window_closed_(false), | 260 window_closed_(false), |
| 262 disable_inactive_rendering_(false), | 261 disable_inactive_rendering_(false), |
| 263 saved_maximized_state_(0) { | 262 saved_maximized_state_(0) { |
| 264 InitClass(); | 263 InitClass(); |
| 265 DCHECK(window_delegate_); | 264 DCHECK(window_delegate_); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 InitAlwaysOnTopState(); | 299 InitAlwaysOnTopState(); |
| 301 | 300 |
| 302 if (!IsAppWindow()) { | 301 if (!IsAppWindow()) { |
| 303 notification_registrar_.Add( | 302 notification_registrar_.Add( |
| 304 this, | 303 this, |
| 305 NotificationType::ALL_APPWINDOWS_CLOSED, | 304 NotificationType::ALL_APPWINDOWS_CLOSED, |
| 306 NotificationService::AllSources()); | 305 NotificationService::AllSources()); |
| 307 } | 306 } |
| 308 } | 307 } |
| 309 | 308 |
| 310 void Window::SetClientView(ClientView* client_view) { | |
| 311 DCHECK(client_view && !client_view_ && GetHWND()); | |
| 312 client_view_ = client_view; | |
| 313 if (non_client_view_) { | |
| 314 // This will trigger the ClientView to be added by the non-client view. | |
| 315 WidgetWin::SetContentsView(non_client_view_); | |
| 316 } else { | |
| 317 WidgetWin::SetContentsView(client_view_); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 void Window::SizeWindowToDefault() { | 309 void Window::SizeWindowToDefault() { |
| 322 gfx::Size pref; | 310 gfx::Size pref = non_client_view_->GetPreferredSize(); |
| 323 if (non_client_view_) { | |
| 324 pref = non_client_view_->GetPreferredSize(); | |
| 325 } else { | |
| 326 pref = client_view_->GetPreferredSize(); | |
| 327 } | |
| 328 DCHECK(pref.width() > 0 && pref.height() > 0); | 311 DCHECK(pref.width() > 0 && pref.height() > 0); |
| 329 // CenterAndSizeWindow adjusts the window size to accommodate the non-client | 312 // CenterAndSizeWindow adjusts the window size to accommodate the non-client |
| 330 // area. | 313 // area. |
| 331 win_util::CenterAndSizeWindow(owning_window(), GetHWND(), pref.ToSIZE(), | 314 win_util::CenterAndSizeWindow(owning_window(), GetHWND(), pref.ToSIZE(), |
| 332 true); | 315 true); |
| 333 } | 316 } |
| 334 | 317 |
| 335 void Window::RunSystemMenu(const gfx::Point& point) { | 318 void Window::RunSystemMenu(const gfx::Point& point) { |
| 336 // We need to reset and clean up any currently created system menu objects. | 319 // We need to reset and clean up any currently created system menu objects. |
| 337 // We need to call this otherwise there's a small chance that we aren't going | 320 // We need to call this otherwise there's a small chance that we aren't going |
| (...skipping 29 matching lines...) Expand all Loading... |
| 367 // messages even after the window is destroyed. | 350 // messages even after the window is destroyed. |
| 368 // If the notification code is > 1 it means it is control specific and we | 351 // If the notification code is > 1 it means it is control specific and we |
| 369 // should ignore it. | 352 // should ignore it. |
| 370 if (notification_code > 1 || !window_delegate_ || | 353 if (notification_code > 1 || !window_delegate_ || |
| 371 window_delegate_->ExecuteWindowsCommand(command_id)) { | 354 window_delegate_->ExecuteWindowsCommand(command_id)) { |
| 372 WidgetWin::OnCommand(notification_code, command_id, window); | 355 WidgetWin::OnCommand(notification_code, command_id, window); |
| 373 } | 356 } |
| 374 } | 357 } |
| 375 | 358 |
| 376 void Window::OnDestroy() { | 359 void Window::OnDestroy() { |
| 377 if (client_view_) { | 360 non_client_view_->WindowClosing(); |
| 378 client_view_->WindowClosing(); | 361 window_delegate_ = NULL; |
| 379 window_delegate_ = NULL; | |
| 380 } | |
| 381 RestoreEnabledIfNecessary(); | 362 RestoreEnabledIfNecessary(); |
| 382 WidgetWin::OnDestroy(); | 363 WidgetWin::OnDestroy(); |
| 383 } | 364 } |
| 384 | 365 |
| 385 LRESULT Window::OnNCActivate(BOOL active) { | 366 LRESULT Window::OnNCActivate(BOOL active) { |
| 386 if (disable_inactive_rendering_) { | 367 if (disable_inactive_rendering_) { |
| 387 disable_inactive_rendering_ = false; | 368 disable_inactive_rendering_ = false; |
| 388 return DefWindowProc(GetHWND(), WM_NCACTIVATE, TRUE, 0); | 369 return DefWindowProc(GetHWND(), WM_NCACTIVATE, TRUE, 0); |
| 389 } | 370 } |
| 390 // Otherwise just do the default thing. | 371 // Otherwise just do the default thing. |
| 391 return WidgetWin::OnNCActivate(active); | 372 return WidgetWin::OnNCActivate(active); |
| 392 } | 373 } |
| 393 | 374 |
| 394 LRESULT Window::OnNCHitTest(const CPoint& point) { | 375 LRESULT Window::OnNCHitTest(const CPoint& point) { |
| 395 // First, give the ClientView a chance to test the point to see if it is part | 376 // First, give the ClientView a chance to test the point to see if it is part |
| 396 // of the non-client area. | 377 // of the non-client area. |
| 397 CPoint temp = point; | 378 CPoint temp = point; |
| 398 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); | 379 MapWindowPoints(HWND_DESKTOP, GetHWND(), &temp, 1); |
| 399 int component = HTNOWHERE; | 380 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); |
| 400 if (non_client_view_) { | |
| 401 component = non_client_view_->NonClientHitTest(gfx::Point(temp)); | |
| 402 } else { | |
| 403 component = client_view_->NonClientHitTest(gfx::Point(temp)); | |
| 404 } | |
| 405 if (component != HTNOWHERE) | 381 if (component != HTNOWHERE) |
| 406 return component; | 382 return component; |
| 407 | 383 |
| 408 // Otherwise, we let Windows do all the native frame non-client handling for | 384 // Otherwise, we let Windows do all the native frame non-client handling for |
| 409 // us. | 385 // us. |
| 410 SetMsgHandled(FALSE); | 386 SetMsgHandled(FALSE); |
| 411 return 0; | 387 return 0; |
| 412 } | 388 } |
| 413 | 389 |
| 414 void Window::OnNCLButtonDown(UINT ht_component, const CPoint& point) { | 390 void Window::OnNCLButtonDown(UINT ht_component, const CPoint& point) { |
| 415 if (ht_component == HTSYSMENU) { | 391 if (ht_component == HTSYSMENU) |
| 416 gfx::Point system_menu_point; | 392 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); |
| 417 if (non_client_view_) { | 393 else |
| 418 system_menu_point = non_client_view_->GetSystemMenuPoint(); | |
| 419 } else { | |
| 420 CPoint temp(0, -NonClientView::kFrameShadowThickness); | |
| 421 MapWindowPoints(GetHWND(), HWND_DESKTOP, &temp, 1); | |
| 422 system_menu_point = gfx::Point(temp); | |
| 423 } | |
| 424 RunSystemMenu(system_menu_point); | |
| 425 } else { | |
| 426 WidgetWin::OnNCLButtonDown(ht_component, point); | 394 WidgetWin::OnNCLButtonDown(ht_component, point); |
| 427 } | |
| 428 } | 395 } |
| 429 | 396 |
| 430 void Window::OnNCRButtonDown(UINT ht_component, const CPoint& point) { | 397 void Window::OnNCRButtonDown(UINT ht_component, const CPoint& point) { |
| 431 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) | 398 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) |
| 432 RunSystemMenu(gfx::Point(point)); | 399 RunSystemMenu(gfx::Point(point)); |
| 433 else | 400 else |
| 434 WidgetWin::OnNCRButtonDown(ht_component, point); | 401 WidgetWin::OnNCRButtonDown(ht_component, point); |
| 435 } | 402 } |
| 436 | 403 |
| 437 | 404 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 BOOL r = ::GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, | 439 BOOL r = ::GetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, |
| 473 FALSE, &menu_info); | 440 FALSE, &menu_info); |
| 474 DCHECK(r); | 441 DCHECK(r); |
| 475 menu_info.fMask = MIIM_STATE; | 442 menu_info.fMask = MIIM_STATE; |
| 476 if (is_always_on_top_) | 443 if (is_always_on_top_) |
| 477 menu_info.fState = MFS_CHECKED; | 444 menu_info.fState = MFS_CHECKED; |
| 478 r = ::SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); | 445 r = ::SetMenuItemInfo(system_menu, IDC_ALWAYS_ON_TOP, FALSE, &menu_info); |
| 479 | 446 |
| 480 // Now change the actual window's behavior. | 447 // Now change the actual window's behavior. |
| 481 AlwaysOnTopChanged(); | 448 AlwaysOnTopChanged(); |
| 482 } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE) && | 449 } else if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { |
| 483 non_client_view_) { | |
| 484 // Run the system menu at the NonClientView's desired location. | 450 // Run the system menu at the NonClientView's desired location. |
| 485 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); | 451 RunSystemMenu(non_client_view_->GetSystemMenuPoint()); |
| 486 } else { | 452 } else { |
| 487 // Use the default implementation for any other command. | 453 // Use the default implementation for any other command. |
| 488 DefWindowProc(GetHWND(), WM_SYSCOMMAND, notification_code, | 454 DefWindowProc(GetHWND(), WM_SYSCOMMAND, notification_code, |
| 489 MAKELPARAM(click.y, click.x)); | 455 MAKELPARAM(click.y, click.x)); |
| 490 } | 456 } |
| 491 } | 457 } |
| 492 | 458 |
| 493 //////////////////////////////////////////////////////////////////////////////// | 459 //////////////////////////////////////////////////////////////////////////////// |
| 494 // Window, private: | 460 // Window, private: |
| 495 | 461 |
| 462 void Window::SetClientView(ClientView* client_view) { |
| 463 DCHECK(client_view && GetHWND()); |
| 464 non_client_view_->set_client_view(client_view); |
| 465 // This will trigger the ClientView to be added by the non-client view. |
| 466 WidgetWin::SetContentsView(non_client_view_); |
| 467 } |
| 468 |
| 496 void Window::BecomeModal() { | 469 void Window::BecomeModal() { |
| 497 // We implement modality by crawling up the hierarchy of windows starting | 470 // We implement modality by crawling up the hierarchy of windows starting |
| 498 // at the owner, disabling all of them so that they don't receive input | 471 // at the owner, disabling all of them so that they don't receive input |
| 499 // messages. | 472 // messages. |
| 500 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; | 473 DCHECK(owning_hwnd_) << "Can't create a modal dialog without an owner"; |
| 501 HWND start = owning_hwnd_; | 474 HWND start = owning_hwnd_; |
| 502 while (start != NULL) { | 475 while (start != NULL) { |
| 503 ::EnableWindow(start, FALSE); | 476 ::EnableWindow(start, FALSE); |
| 504 start = ::GetParent(start); | 477 start = ::GetParent(start); |
| 505 } | 478 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 void Window::InitClass() { | 651 void Window::InitClass() { |
| 679 static bool initialized = false; | 652 static bool initialized = false; |
| 680 if (!initialized) { | 653 if (!initialized) { |
| 681 nwse_cursor_ = LoadCursor(NULL, IDC_SIZENWSE); | 654 nwse_cursor_ = LoadCursor(NULL, IDC_SIZENWSE); |
| 682 initialized = true; | 655 initialized = true; |
| 683 } | 656 } |
| 684 } | 657 } |
| 685 | 658 |
| 686 } // namespace views | 659 } // namespace views |
| 687 | 660 |
| OLD | NEW |