Chromium Code Reviews| 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/widget.h" | 5 #include "views/widget/widget.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "ui/base/l10n/l10n_font_util.h" | 10 #include "ui/base/l10n/l10n_font_util.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 delegate(NULL), | 94 delegate(NULL), |
| 95 child(false), | 95 child(false), |
| 96 transient(false), | 96 transient(false), |
| 97 transparent(false), | 97 transparent(false), |
| 98 accept_events(true), | 98 accept_events(true), |
| 99 can_activate(true), | 99 can_activate(true), |
| 100 keep_on_top(false), | 100 keep_on_top(false), |
| 101 ownership(NATIVE_WIDGET_OWNS_WIDGET), | 101 ownership(NATIVE_WIDGET_OWNS_WIDGET), |
| 102 mirror_origin_in_rtl(false), | 102 mirror_origin_in_rtl(false), |
| 103 has_dropshadow(false), | 103 has_dropshadow(false), |
| 104 maximize(false), | 104 show_state(ui::SHOW_STATE_DEFAULT), |
| 105 double_buffer(false), | 105 double_buffer(false), |
| 106 parent(NULL), | 106 parent(NULL), |
| 107 parent_widget(NULL), | 107 parent_widget(NULL), |
| 108 native_widget(NULL), | 108 native_widget(NULL), |
| 109 top_level(false) { | 109 top_level(false) { |
| 110 } | 110 } |
| 111 | 111 |
| 112 Widget::InitParams::InitParams(Type type) | 112 Widget::InitParams::InitParams(Type type) |
| 113 : type(type), | 113 : type(type), |
| 114 delegate(NULL), | 114 delegate(NULL), |
| 115 child(type == TYPE_CONTROL), | 115 child(type == TYPE_CONTROL), |
| 116 transient(type == TYPE_POPUP || type == TYPE_MENU), | 116 transient(type == TYPE_POPUP || type == TYPE_MENU), |
| 117 transparent(false), | 117 transparent(false), |
| 118 accept_events(true), | 118 accept_events(true), |
| 119 can_activate(type != TYPE_POPUP && type != TYPE_MENU), | 119 can_activate(type != TYPE_POPUP && type != TYPE_MENU), |
| 120 keep_on_top(type == TYPE_MENU), | 120 keep_on_top(type == TYPE_MENU), |
| 121 ownership(NATIVE_WIDGET_OWNS_WIDGET), | 121 ownership(NATIVE_WIDGET_OWNS_WIDGET), |
| 122 mirror_origin_in_rtl(false), | 122 mirror_origin_in_rtl(false), |
| 123 has_dropshadow(false), | 123 has_dropshadow(false), |
| 124 maximize(false), | 124 show_state(ui::SHOW_STATE_DEFAULT), |
| 125 double_buffer(false), | 125 double_buffer(false), |
| 126 parent(NULL), | 126 parent(NULL), |
| 127 parent_widget(NULL), | 127 parent_widget(NULL), |
| 128 native_widget(NULL), | 128 native_widget(NULL), |
| 129 top_level(false) { | 129 top_level(false) { |
| 130 } | 130 } |
| 131 | 131 |
| 132 //////////////////////////////////////////////////////////////////////////////// | 132 //////////////////////////////////////////////////////////////////////////////// |
| 133 // Widget, public: | 133 // Widget, public: |
| 134 | 134 |
| 135 // static | 135 // static |
| 136 Widget::InitParams Widget::WindowInitParams() { | 136 Widget::InitParams Widget::WindowInitParams() { |
| 137 return InitParams(InitParams::TYPE_WINDOW); | 137 return InitParams(InitParams::TYPE_WINDOW); |
| 138 } | 138 } |
| 139 | 139 |
| 140 Widget::Widget() | 140 Widget::Widget() |
| 141 : is_mouse_button_pressed_(false), | 141 : is_mouse_button_pressed_(false), |
| 142 last_mouse_event_was_move_(false), | 142 last_mouse_event_was_move_(false), |
| 143 native_widget_(NULL), | 143 native_widget_(NULL), |
| 144 widget_delegate_(NULL), | 144 widget_delegate_(NULL), |
| 145 non_client_view_(NULL), | 145 non_client_view_(NULL), |
| 146 dragged_view_(NULL), | 146 dragged_view_(NULL), |
| 147 event_stack_(), | 147 event_stack_(), |
| 148 ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET), | 148 ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET), |
| 149 is_secondary_widget_(true), | 149 is_secondary_widget_(true), |
| 150 frame_type_(FRAME_TYPE_DEFAULT), | 150 frame_type_(FRAME_TYPE_DEFAULT), |
| 151 disable_inactive_rendering_(false), | 151 disable_inactive_rendering_(false), |
| 152 widget_closed_(false), | 152 widget_closed_(false), |
| 153 saved_maximized_state_(false), | 153 saved_show_state_(ui::SHOW_STATE_DEFAULT), |
| 154 minimum_size_(100, 100), | 154 minimum_size_(100, 100), |
| 155 focus_on_creation_(true), | 155 focus_on_creation_(true), |
| 156 is_top_level_(false), | 156 is_top_level_(false), |
| 157 destroy_state_(DESTROY_STATE_NONE) { | 157 destroy_state_(DESTROY_STATE_NONE) { |
| 158 } | 158 } |
| 159 | 159 |
| 160 Widget::~Widget() { | 160 Widget::~Widget() { |
| 161 destroy_state_ = DESTROY_STATE_DELETED; | 161 destroy_state_ = DESTROY_STATE_DELETED; |
| 162 | 162 |
| 163 while (!event_stack_.empty()) { | 163 while (!event_stack_.empty()) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 } | 299 } |
| 300 native_widget_->InitNativeWidget(params); | 300 native_widget_->InitNativeWidget(params); |
| 301 if (params.type == InitParams::TYPE_WINDOW) { | 301 if (params.type == InitParams::TYPE_WINDOW) { |
| 302 non_client_view_ = new NonClientView; | 302 non_client_view_ = new NonClientView; |
| 303 non_client_view_->SetFrameView(CreateNonClientFrameView()); | 303 non_client_view_->SetFrameView(CreateNonClientFrameView()); |
| 304 // Create the ClientView, add it to the NonClientView and add the | 304 // Create the ClientView, add it to the NonClientView and add the |
| 305 // NonClientView to the RootView. This will cause everything to be parented. | 305 // NonClientView to the RootView. This will cause everything to be parented. |
| 306 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); | 306 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); |
| 307 SetContentsView(non_client_view_); | 307 SetContentsView(non_client_view_); |
| 308 SetInitialBounds(params.bounds); | 308 SetInitialBounds(params.bounds); |
| 309 if (params.maximize) | 309 if (params.show_state == ui::SHOW_STATE_MAXIMIZED) |
| 310 Maximize(); | 310 Maximize(); |
| 311 else if (params.show_state == ui::SHOW_STATE_MINIMIZED) | |
| 312 Minimize(); | |
| 311 UpdateWindowTitle(); | 313 UpdateWindowTitle(); |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 // Unconverted methods (see header) -------------------------------------------- | 317 // Unconverted methods (see header) -------------------------------------------- |
| 316 | 318 |
| 317 gfx::NativeView Widget::GetNativeView() const { | 319 gfx::NativeView Widget::GetNativeView() const { |
| 318 return native_widget_->GetNativeView(); | 320 return native_widget_->GetNativeView(); |
| 319 } | 321 } |
| 320 | 322 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 } | 463 } |
| 462 | 464 |
| 463 void Widget::EnableClose(bool enable) { | 465 void Widget::EnableClose(bool enable) { |
| 464 if (non_client_view_) | 466 if (non_client_view_) |
| 465 non_client_view_->EnableClose(enable); | 467 non_client_view_->EnableClose(enable); |
| 466 native_widget_->EnableClose(enable); | 468 native_widget_->EnableClose(enable); |
| 467 } | 469 } |
| 468 | 470 |
| 469 void Widget::Show() { | 471 void Widget::Show() { |
| 470 if (non_client_view_) { | 472 if (non_client_view_) { |
| 471 if (saved_maximized_state_ && !initial_restored_bounds_.IsEmpty()) { | 473 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED && |
| 474 !initial_restored_bounds_.IsEmpty()) { | |
| 472 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_); | 475 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_); |
| 473 } else { | 476 } else { |
| 474 native_widget_->ShowWithState(saved_maximized_state_ ? | 477 native_widget_->ShowWithWindowState(saved_show_state_); |
| 475 internal::NativeWidgetPrivate::SHOW_MAXIMIZED : | |
| 476 internal::NativeWidgetPrivate::SHOW_RESTORED); | |
| 477 } | 478 } |
| 478 // |saved_maximized_state_| only applies the first time the window is shown. | 479 // |saved_show_state_| only applies the first time the window is shown. |
| 479 // If we don't reset the value the window will be shown maximized every time | 480 // If we don't reset the value the window may be shown maximized every time |
| 480 // it is subsequently shown after being hidden. | 481 // it is subsequently shown after being hidden. |
| 481 saved_maximized_state_ = false; | 482 saved_show_state_ = ui::SHOW_STATE_NORMAL; |
| 482 } else { | 483 } else { |
| 483 native_widget_->Show(); | 484 native_widget_->Show(); |
| 484 } | 485 } |
| 485 } | 486 } |
| 486 | 487 |
| 487 void Widget::Hide() { | 488 void Widget::Hide() { |
| 488 native_widget_->Hide(); | 489 native_widget_->Hide(); |
| 489 } | 490 } |
| 490 | 491 |
| 491 void Widget::ShowInactive() { | 492 void Widget::ShowInactive() { |
| 492 // If this gets called with saved_maximized_state_ == true, call SetBounds() | 493 // If this gets called with saved_show_state_ == ui::SHOW_STATE_MAXIMIZED, |
| 493 // with the restored bounds to set the correct size. This normally should | 494 // call SetBounds()with the restored bounds to set the correct size. This |
| 494 // not happen, but if it does we should avoid showing unsized windows. | 495 // normally should not happen, but if it does we should avoid showing unsized |
| 495 if (saved_maximized_state_ && !initial_restored_bounds_.IsEmpty()) { | 496 // windows. |
| 497 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED && | |
| 498 !initial_restored_bounds_.IsEmpty()) { | |
| 496 SetBounds(initial_restored_bounds_); | 499 SetBounds(initial_restored_bounds_); |
| 497 saved_maximized_state_ = false; | 500 saved_show_state_ = ui::SHOW_STATE_NORMAL; |
| 498 } | 501 } |
| 499 native_widget_->ShowWithState(internal::NativeWidgetPrivate::SHOW_INACTIVE); | 502 native_widget_->ShowWithWindowState(ui::SHOW_STATE_INACTIVE); |
| 500 } | 503 } |
| 501 | 504 |
| 502 void Widget::Activate() { | 505 void Widget::Activate() { |
| 503 native_widget_->Activate(); | 506 native_widget_->Activate(); |
| 504 } | 507 } |
| 505 | 508 |
| 506 void Widget::Deactivate() { | 509 void Widget::Deactivate() { |
| 507 native_widget_->Deactivate(); | 510 native_widget_->Deactivate(); |
| 508 } | 511 } |
| 509 | 512 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 widget_delegate_->DeleteDelegate(); | 882 widget_delegate_->DeleteDelegate(); |
| 880 widget_delegate_ = NULL; | 883 widget_delegate_ = NULL; |
| 881 } | 884 } |
| 882 | 885 |
| 883 gfx::Size Widget::GetMinimumSize() { | 886 gfx::Size Widget::GetMinimumSize() { |
| 884 return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size(); | 887 return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size(); |
| 885 } | 888 } |
| 886 | 889 |
| 887 void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) { | 890 void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) { |
| 888 root_view_->SetSize(new_size); | 891 root_view_->SetSize(new_size); |
| 892 // Having a focus manager is a signal that proper initialization has taken | |
| 893 // place. Size changed notifications can fire prior to full initialization | |
| 894 // i.e. during session restore. Avoid saving session state during these | |
| 895 // startup procedures. | |
| 896 if (HasFocusManager()) | |
|
sky
2011/08/26 16:26:20
This seems a bit fragile. Could you instead add an
dhollowa
2011/08/26 22:13:50
Done.
| |
| 897 SaveWindowPosition(); | |
| 889 } | 898 } |
| 890 | 899 |
| 891 void Widget::OnNativeWidgetBeginUserBoundsChange() { | 900 void Widget::OnNativeWidgetBeginUserBoundsChange() { |
| 892 widget_delegate_->OnWindowBeginUserBoundsChange(); | 901 widget_delegate_->OnWindowBeginUserBoundsChange(); |
| 893 } | 902 } |
| 894 | 903 |
| 895 void Widget::OnNativeWidgetEndUserBoundsChange() { | 904 void Widget::OnNativeWidgetEndUserBoundsChange() { |
| 896 widget_delegate_->OnWindowEndUserBoundsChange(); | 905 widget_delegate_->OnWindowEndUserBoundsChange(); |
| 897 } | 906 } |
| 898 | 907 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 } | 1065 } |
| 1057 | 1066 |
| 1058 void Widget::SaveWindowPosition() { | 1067 void Widget::SaveWindowPosition() { |
| 1059 // The window delegate does the actual saving for us. It seems like (judging | 1068 // The window delegate does the actual saving for us. It seems like (judging |
| 1060 // by go/crash) that in some circumstances we can end up here after | 1069 // by go/crash) that in some circumstances we can end up here after |
| 1061 // WM_DESTROY, at which point the window delegate is likely gone. So just | 1070 // WM_DESTROY, at which point the window delegate is likely gone. So just |
| 1062 // bail. | 1071 // bail. |
| 1063 if (!widget_delegate_) | 1072 if (!widget_delegate_) |
| 1064 return; | 1073 return; |
| 1065 | 1074 |
| 1066 bool maximized = false; | 1075 ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL; |
| 1067 gfx::Rect bounds; | 1076 gfx::Rect bounds; |
| 1068 native_widget_->GetWindowBoundsAndMaximizedState(&bounds, &maximized); | 1077 native_widget_->GetWindowBoundsAndShowState(&bounds, &show_state); |
| 1069 widget_delegate_->SaveWindowPlacement(bounds, maximized); | 1078 widget_delegate_->SaveWindowPlacement(bounds, show_state); |
| 1070 } | 1079 } |
| 1071 | 1080 |
| 1072 void Widget::SetInitialBounds(const gfx::Rect& bounds) { | 1081 void Widget::SetInitialBounds(const gfx::Rect& bounds) { |
| 1073 if (!non_client_view_) | 1082 if (!non_client_view_) |
| 1074 return; | 1083 return; |
| 1075 | 1084 |
| 1076 gfx::Rect saved_bounds; | 1085 gfx::Rect saved_bounds; |
| 1077 if (GetSavedBounds(&saved_bounds, &saved_maximized_state_)) { | 1086 if (GetSavedBounds(&saved_bounds, &saved_show_state_)) { |
| 1078 if (saved_maximized_state_) { | 1087 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED) { |
| 1079 // If we're going to maximize, wait until Show is invoked to set the | 1088 // If we're going to maximize, wait until Show is invoked to set the |
| 1080 // bounds. That way we avoid a noticable resize. | 1089 // bounds. That way we avoid a noticable resize. |
| 1081 initial_restored_bounds_ = saved_bounds; | 1090 initial_restored_bounds_ = saved_bounds; |
| 1082 } else { | 1091 } else { |
| 1083 SetBounds(saved_bounds); | 1092 SetBounds(saved_bounds); |
| 1084 } | 1093 } |
| 1085 } else { | 1094 } else { |
| 1086 if (bounds.IsEmpty()) { | 1095 if (bounds.IsEmpty()) { |
| 1087 // No initial bounds supplied, so size the window to its content and | 1096 // No initial bounds supplied, so size the window to its content and |
| 1088 // center over its parent. | 1097 // center over its parent. |
| 1089 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); | 1098 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); |
| 1090 } else { | 1099 } else { |
| 1091 // Use the supplied initial bounds. | 1100 // Use the supplied initial bounds. |
| 1092 SetBoundsConstrained(bounds, NULL); | 1101 SetBoundsConstrained(bounds, NULL); |
| 1093 } | 1102 } |
| 1094 } | 1103 } |
| 1095 } | 1104 } |
| 1096 | 1105 |
| 1097 bool Widget::GetSavedBounds(gfx::Rect* bounds, bool* maximize) { | 1106 bool Widget::GetSavedBounds(gfx::Rect* bounds, |
| 1107 ui::WindowShowState* show_state) { | |
| 1098 // First we obtain the window's saved show-style and store it. We need to do | 1108 // First we obtain the window's saved show-style and store it. We need to do |
| 1099 // this here, rather than in Show() because by the time Show() is called, | 1109 // this here, rather than in Show() because by the time Show() is called, |
| 1100 // the window's size will have been reset (below) and the saved maximized | 1110 // the window's size will have been reset (below) and the saved maximized |
| 1101 // state will have been lost. Sadly there's no way to tell on Windows when | 1111 // state will have been lost. Sadly there's no way to tell on Windows when |
| 1102 // a window is restored from maximized state, so we can't more accurately | 1112 // a window is restored from maximized state, so we can't more accurately |
| 1103 // track maximized state independently of sizing information. | 1113 // track maximized state independently of sizing information. |
| 1104 widget_delegate_->GetSavedMaximizedState(maximize); | 1114 widget_delegate_->GetSavedWindowShowState(show_state); |
| 1105 | 1115 |
| 1106 // Restore the window's placement from the controller. | 1116 // Restore the window's placement from the controller. |
| 1107 if (widget_delegate_->GetSavedWindowBounds(bounds)) { | 1117 if (widget_delegate_->GetSavedWindowBounds(bounds)) { |
| 1108 if (!widget_delegate_->ShouldRestoreWindowSize()) { | 1118 if (!widget_delegate_->ShouldRestoreWindowSize()) { |
| 1109 bounds->set_size(non_client_view_->GetPreferredSize()); | 1119 bounds->set_size(non_client_view_->GetPreferredSize()); |
| 1110 } else { | 1120 } else { |
| 1111 // Make sure the bounds are at least the minimum size. | 1121 // Make sure the bounds are at least the minimum size. |
| 1112 if (bounds->width() < minimum_size_.width()) | 1122 if (bounds->width() < minimum_size_.width()) |
| 1113 bounds->set_width(minimum_size_.width()); | 1123 bounds->set_width(minimum_size_.width()); |
| 1114 | 1124 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1134 | 1144 |
| 1135 //////////////////////////////////////////////////////////////////////////////// | 1145 //////////////////////////////////////////////////////////////////////////////// |
| 1136 // internal::NativeWidgetPrivate, NativeWidget implementation: | 1146 // internal::NativeWidgetPrivate, NativeWidget implementation: |
| 1137 | 1147 |
| 1138 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { | 1148 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { |
| 1139 return this; | 1149 return this; |
| 1140 } | 1150 } |
| 1141 | 1151 |
| 1142 } // namespace internal | 1152 } // namespace internal |
| 1143 } // namespace views | 1153 } // namespace views |
| OLD | NEW |