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 |