widget.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/views/widget/widget.h" 6 7#include "base/debug/trace_event.h" 8#include "base/logging.h" 9#include "base/message_loop.h" 10#include "base/strings/utf_string_conversions.h" 11#include "ui/base/default_theme_provider.h" 12#include "ui/base/events/event.h" 13#include "ui/base/hit_test.h" 14#include "ui/base/l10n/l10n_font_util.h" 15#include "ui/base/resource/resource_bundle.h" 16#include "ui/compositor/compositor.h" 17#include "ui/compositor/layer.h" 18#include "ui/gfx/screen.h" 19#include "ui/views/focus/focus_manager.h" 20#include "ui/views/focus/focus_manager_factory.h" 21#include "ui/views/focus/view_storage.h" 22#include "ui/views/focus/widget_focus_manager.h" 23#include "ui/views/ime/input_method.h" 24#include "ui/views/views_delegate.h" 25#include "ui/views/widget/native_widget_private.h" 26#include "ui/views/widget/root_view.h" 27#include "ui/views/widget/tooltip_manager.h" 28#include "ui/views/widget/widget_delegate.h" 29#include "ui/views/widget/widget_deletion_observer.h" 30#include "ui/views/widget/widget_observer.h" 31#include "ui/views/window/custom_frame_view.h" 32 33#if !defined(OS_MACOSX) 34#include "ui/views/controls/menu/menu_controller.h" 35#endif 36 37namespace views { 38 39namespace { 40 41// If |view| has a layer the layer is added to |layers|. Else this recurses 42// through the children. This is used to build a list of the layers created by 43// views that are direct children of the Widgets layer. 44void BuildRootLayers(View* view, std::vector<ui::Layer*>* layers) { 45 if (view->layer()) { 46 layers->push_back(view->layer()); 47 } else { 48 for (int i = 0; i < view->child_count(); ++i) 49 BuildRootLayers(view->child_at(i), layers); 50 } 51} 52 53// Create a native widget implementation. 54// First, use the supplied one if non-NULL. 55// Finally, make a default one. 56NativeWidget* CreateNativeWidget(NativeWidget* native_widget, 57 internal::NativeWidgetDelegate* delegate) { 58 if (!native_widget) { 59 native_widget = 60 internal::NativeWidgetPrivate::CreateNativeWidget(delegate); 61 } 62 return native_widget; 63} 64 65} // namespace 66 67// A default implementation of WidgetDelegate, used by Widget when no 68// WidgetDelegate is supplied. 69class DefaultWidgetDelegate : public WidgetDelegate { 70 public: 71 DefaultWidgetDelegate(Widget* widget, const Widget::InitParams& params) 72 : widget_(widget), 73 can_activate_(!params.child && 74 params.type != Widget::InitParams::TYPE_POPUP) { 75 } 76 virtual ~DefaultWidgetDelegate() {} 77 78 // Overridden from WidgetDelegate: 79 virtual void DeleteDelegate() OVERRIDE { 80 delete this; 81 } 82 virtual Widget* GetWidget() OVERRIDE { 83 return widget_; 84 } 85 virtual const Widget* GetWidget() const OVERRIDE { 86 return widget_; 87 } 88 89 virtual bool CanActivate() const OVERRIDE { 90 return can_activate_; 91 } 92 93 private: 94 Widget* widget_; 95 bool can_activate_; 96 97 DISALLOW_COPY_AND_ASSIGN(DefaultWidgetDelegate); 98}; 99 100//////////////////////////////////////////////////////////////////////////////// 101// Widget, InitParams: 102 103Widget::InitParams::InitParams() 104 : type(TYPE_WINDOW), 105 delegate(NULL), 106 child(false), 107 opacity((ViewsDelegate::views_delegate && 108 ViewsDelegate::views_delegate->UseTransparentWindows()) ? 109 TRANSLUCENT_WINDOW : INFER_OPACITY), 110 accept_events(true), 111 can_activate(true), 112 keep_on_top(false), 113 ownership(NATIVE_WIDGET_OWNS_WIDGET), 114 mirror_origin_in_rtl(false), 115 has_dropshadow(false), 116 remove_standard_frame(false), 117 use_system_default_icon(false), 118 show_state(ui::SHOW_STATE_DEFAULT), 119 double_buffer(false), 120 parent(NULL), 121 native_widget(NULL), 122 desktop_root_window_host(NULL), 123 top_level(false), 124 layer_type(ui::LAYER_TEXTURED), 125 context(NULL) { 126} 127 128Widget::InitParams::InitParams(Type type) 129 : type(type), 130 delegate(NULL), 131 child(type == TYPE_CONTROL), 132 opacity((type == TYPE_WINDOW && 133 ViewsDelegate::views_delegate && 134 ViewsDelegate::views_delegate->UseTransparentWindows()) ? 135 TRANSLUCENT_WINDOW : INFER_OPACITY), 136 accept_events(true), 137 can_activate(type != TYPE_POPUP && type != TYPE_MENU), 138 keep_on_top(type == TYPE_MENU), 139 ownership(NATIVE_WIDGET_OWNS_WIDGET), 140 mirror_origin_in_rtl(false), 141 has_dropshadow(false), 142 remove_standard_frame(false), 143 use_system_default_icon(false), 144 show_state(ui::SHOW_STATE_DEFAULT), 145 double_buffer(false), 146 parent(NULL), 147 native_widget(NULL), 148 desktop_root_window_host(NULL), 149 top_level(false), 150 layer_type(ui::LAYER_TEXTURED), 151 context(NULL) { 152} 153 154//////////////////////////////////////////////////////////////////////////////// 155// Widget, public: 156 157Widget::Widget() 158 : native_widget_(NULL), 159 widget_delegate_(NULL), 160 non_client_view_(NULL), 161 dragged_view_(NULL), 162 ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET), 163 is_secondary_widget_(true), 164 frame_type_(FRAME_TYPE_DEFAULT), 165 disable_inactive_rendering_(false), 166 widget_closed_(false), 167 saved_show_state_(ui::SHOW_STATE_DEFAULT), 168 focus_on_creation_(true), 169 is_top_level_(false), 170 native_widget_initialized_(false), 171 native_widget_destroyed_(false), 172 is_mouse_button_pressed_(false), 173 is_touch_down_(false), 174 last_mouse_event_was_move_(false), 175 root_layers_dirty_(false), 176 movement_disabled_(false) { 177} 178 179Widget::~Widget() { 180 DestroyRootView(); 181 if (ownership_ == InitParams::WIDGET_OWNS_NATIVE_WIDGET) { 182 delete native_widget_; 183 } else { 184 DCHECK(native_widget_destroyed_) 185 << "Destroying a widget with a live native widget. " 186 << "Widget probably should use WIDGET_OWNS_NATIVE_WIDGET ownership."; 187 } 188} 189 190// static 191Widget* Widget::CreateWindow(WidgetDelegate* delegate) { 192 return CreateWindowWithBounds(delegate, gfx::Rect()); 193} 194 195// static 196Widget* Widget::CreateWindowWithBounds(WidgetDelegate* delegate, 197 const gfx::Rect& bounds) { 198 Widget* widget = new Widget; 199 Widget::InitParams params; 200 params.bounds = bounds; 201 params.delegate = delegate; 202 params.top_level = true; 203 widget->Init(params); 204 return widget; 205} 206 207// static 208Widget* Widget::CreateWindowWithParent(WidgetDelegate* delegate, 209 gfx::NativeWindow parent) { 210 return CreateWindowWithParentAndBounds(delegate, parent, gfx::Rect()); 211} 212 213// static 214Widget* Widget::CreateWindowWithParentAndBounds(WidgetDelegate* delegate, 215 gfx::NativeWindow parent, 216 const gfx::Rect& bounds) { 217 Widget* widget = new Widget; 218 Widget::InitParams params; 219 params.delegate = delegate; 220 params.parent = parent; 221 params.bounds = bounds; 222 widget->Init(params); 223 return widget; 224} 225 226// static 227Widget* Widget::CreateWindowWithContext(WidgetDelegate* delegate, 228 gfx::NativeView context) { 229 return CreateWindowWithContextAndBounds(delegate, context, gfx::Rect()); 230} 231 232// static 233Widget* Widget::CreateWindowWithContextAndBounds(WidgetDelegate* delegate, 234 gfx::NativeView context, 235 const gfx::Rect& bounds) { 236 Widget* widget = new Widget; 237 Widget::InitParams params; 238 params.delegate = delegate; 239 params.context = context; 240 params.bounds = bounds; 241 widget->Init(params); 242 return widget; 243} 244 245// static 246Widget* Widget::GetWidgetForNativeView(gfx::NativeView native_view) { 247 internal::NativeWidgetPrivate* native_widget = 248 internal::NativeWidgetPrivate::GetNativeWidgetForNativeView(native_view); 249 return native_widget ? native_widget->GetWidget() : NULL; 250} 251 252// static 253Widget* Widget::GetWidgetForNativeWindow(gfx::NativeWindow native_window) { 254 internal::NativeWidgetPrivate* native_widget = 255 internal::NativeWidgetPrivate::GetNativeWidgetForNativeWindow( 256 native_window); 257 return native_widget ? native_widget->GetWidget() : NULL; 258} 259 260// static 261Widget* Widget::GetTopLevelWidgetForNativeView(gfx::NativeView native_view) { 262 internal::NativeWidgetPrivate* native_widget = 263 internal::NativeWidgetPrivate::GetTopLevelNativeWidget(native_view); 264 return native_widget ? native_widget->GetWidget() : NULL; 265} 266 267 268// static 269void Widget::GetAllChildWidgets(gfx::NativeView native_view, 270 Widgets* children) { 271 internal::NativeWidgetPrivate::GetAllChildWidgets(native_view, children); 272} 273 274// static 275void Widget::ReparentNativeView(gfx::NativeView native_view, 276 gfx::NativeView new_parent) { 277 internal::NativeWidgetPrivate::ReparentNativeView(native_view, new_parent); 278} 279 280// static 281int Widget::GetLocalizedContentsWidth(int col_resource_id) { 282 return ui::GetLocalizedContentsWidthForFont(col_resource_id, 283 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont)); 284} 285 286// static 287int Widget::GetLocalizedContentsHeight(int row_resource_id) { 288 return ui::GetLocalizedContentsHeightForFont(row_resource_id, 289 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont)); 290} 291 292// static 293gfx::Size Widget::GetLocalizedContentsSize(int col_resource_id, 294 int row_resource_id) { 295 return gfx::Size(GetLocalizedContentsWidth(col_resource_id), 296 GetLocalizedContentsHeight(row_resource_id)); 297} 298 299// static 300bool Widget::RequiresNonClientView(InitParams::Type type) { 301 return type == InitParams::TYPE_WINDOW || 302 type == InitParams::TYPE_PANEL || 303 type == InitParams::TYPE_BUBBLE; 304} 305 306void Widget::Init(const InitParams& in_params) { 307 TRACE_EVENT0("views", "Widget::Init"); 308 InitParams params = in_params; 309 310 is_top_level_ = params.top_level || 311 (!params.child && 312 params.type != InitParams::TYPE_CONTROL && 313 params.type != InitParams::TYPE_TOOLTIP); 314 params.top_level = is_top_level_; 315 if (params.opacity == InitParams::INFER_OPACITY) { 316#if defined(OS_WIN) && defined(USE_AURA) 317 // By default, make all top-level windows but the main window transparent 318 // initially so that they can be made to fade in. 319 if (is_top_level_ && params.type != InitParams::TYPE_WINDOW) 320 params.opacity = InitParams::TRANSLUCENT_WINDOW; 321 else 322 params.opacity = InitParams::OPAQUE_WINDOW; 323#else 324 params.opacity = InitParams::OPAQUE_WINDOW; 325#endif 326 } 327 328 if (ViewsDelegate::views_delegate) 329 ViewsDelegate::views_delegate->OnBeforeWidgetInit(¶ms, this); 330 331 widget_delegate_ = params.delegate ? 332 params.delegate : new DefaultWidgetDelegate(this, params); 333 ownership_ = params.ownership; 334 native_widget_ = CreateNativeWidget(params.native_widget, this)-> 335 AsNativeWidgetPrivate(); 336 root_view_.reset(CreateRootView()); 337 default_theme_provider_.reset(new ui::DefaultThemeProvider); 338 if (params.type == InitParams::TYPE_MENU) { 339 is_mouse_button_pressed_ = 340 internal::NativeWidgetPrivate::IsMouseButtonDown(); 341 } 342 native_widget_->InitNativeWidget(params); 343 if (RequiresNonClientView(params.type)) { 344 non_client_view_ = new NonClientView; 345 non_client_view_->SetFrameView(CreateNonClientFrameView()); 346 // Create the ClientView, add it to the NonClientView and add the 347 // NonClientView to the RootView. This will cause everything to be parented. 348 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); 349 non_client_view_->SetOverlayView(widget_delegate_->CreateOverlayView()); 350 SetContentsView(non_client_view_); 351 SetInitialBounds(params.bounds); 352 if (params.show_state == ui::SHOW_STATE_MAXIMIZED) 353 Maximize(); 354 else if (params.show_state == ui::SHOW_STATE_MINIMIZED) 355 Minimize(); 356 UpdateWindowTitle(); 357 } else if (params.delegate) { 358 SetContentsView(params.delegate->GetContentsView()); 359 SetInitialBoundsForFramelessWindow(params.bounds); 360 } 361 native_widget_initialized_ = true; 362} 363 364// Unconverted methods (see header) -------------------------------------------- 365 366gfx::NativeView Widget::GetNativeView() const { 367 return native_widget_->GetNativeView(); 368} 369 370gfx::NativeWindow Widget::GetNativeWindow() const { 371 return native_widget_->GetNativeWindow(); 372} 373 374void Widget::AddObserver(WidgetObserver* observer) { 375 observers_.AddObserver(observer); 376} 377 378void Widget::RemoveObserver(WidgetObserver* observer) { 379 observers_.RemoveObserver(observer); 380} 381 382bool Widget::HasObserver(WidgetObserver* observer) { 383 return observers_.HasObserver(observer); 384} 385 386bool Widget::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { 387 return false; 388} 389 390void Widget::ViewHierarchyChanged( 391 const View::ViewHierarchyChangedDetails& details) { 392 if (!details.is_add) { 393 if (details.child == dragged_view_) 394 dragged_view_ = NULL; 395 FocusManager* focus_manager = GetFocusManager(); 396 if (focus_manager) 397 focus_manager->ViewRemoved(details.child); 398 ViewStorage::GetInstance()->ViewRemoved(details.child); 399 native_widget_->ViewRemoved(details.child); 400 } 401} 402 403void Widget::NotifyNativeViewHierarchyChanged(bool attached, 404 gfx::NativeView native_view) { 405 if (!attached) { 406 FocusManager* focus_manager = GetFocusManager(); 407 // We are being removed from a window hierarchy. Treat this as 408 // the root_view_ being removed. 409 if (focus_manager) 410 focus_manager->ViewRemoved(root_view_.get()); 411 } 412 root_view_->NotifyNativeViewHierarchyChanged(attached, native_view); 413} 414 415// Converted methods (see header) ---------------------------------------------- 416 417Widget* Widget::GetTopLevelWidget() { 418 return const_cast<Widget*>( 419 static_cast<const Widget*>(this)->GetTopLevelWidget()); 420} 421 422const Widget* Widget::GetTopLevelWidget() const { 423 // GetTopLevelNativeWidget doesn't work during destruction because 424 // property is gone after gobject gets deleted. Short circuit here 425 // for toplevel so that InputMethod can remove itself from 426 // focus manager. 427 return is_top_level() ? this : native_widget_->GetTopLevelWidget(); 428} 429 430void Widget::SetContentsView(View* view) { 431 // Do not SetContentsView() again if it is already set to the same view. 432 if (view == GetContentsView()) 433 return; 434 root_view_->SetContentsView(view); 435 if (non_client_view_ != view) { 436 // |non_client_view_| can only be non-NULL here if RequiresNonClientView() 437 // was true when the widget was initialized. Creating widgets with non 438 // client views and then setting the contents view can cause subtle 439 // problems on Windows, where the native widget thinks there is still a 440 // |non_client_view_|. If you get this error, either use a different type 441 // when initializing the widget, or don't call SetContentsView(). 442 DCHECK(!non_client_view_); 443 non_client_view_ = NULL; 444 } 445} 446 447View* Widget::GetContentsView() { 448 return root_view_->GetContentsView(); 449} 450 451gfx::Rect Widget::GetWindowBoundsInScreen() const { 452 return native_widget_->GetWindowBoundsInScreen(); 453} 454 455gfx::Rect Widget::GetClientAreaBoundsInScreen() const { 456 return native_widget_->GetClientAreaBoundsInScreen(); 457} 458 459gfx::Rect Widget::GetRestoredBounds() const { 460 return native_widget_->GetRestoredBounds(); 461} 462 463void Widget::SetBounds(const gfx::Rect& bounds) { 464 native_widget_->SetBounds(bounds); 465} 466 467void Widget::SetSize(const gfx::Size& size) { 468 native_widget_->SetSize(size); 469} 470 471void Widget::CenterWindow(const gfx::Size& size) { 472 native_widget_->CenterWindow(size); 473} 474 475void Widget::SetBoundsConstrained(const gfx::Rect& bounds) { 476 gfx::Rect work_area = 477 gfx::Screen::GetScreenFor(GetNativeView())->GetDisplayNearestPoint( 478 bounds.origin()).work_area(); 479 if (work_area.IsEmpty()) { 480 SetBounds(bounds); 481 } else { 482 // Inset the work area slightly. 483 work_area.Inset(10, 10, 10, 10); 484 work_area.AdjustToFit(bounds); 485 SetBounds(work_area); 486 } 487} 488 489void Widget::SetVisibilityChangedAnimationsEnabled(bool value) { 490 native_widget_->SetVisibilityChangedAnimationsEnabled(value); 491} 492 493Widget::MoveLoopResult Widget::RunMoveLoop(const gfx::Vector2d& drag_offset, 494 MoveLoopSource source) { 495 return native_widget_->RunMoveLoop(drag_offset, source); 496} 497 498void Widget::EndMoveLoop() { 499 native_widget_->EndMoveLoop(); 500} 501 502void Widget::StackAboveWidget(Widget* widget) { 503 native_widget_->StackAbove(widget->GetNativeView()); 504} 505 506void Widget::StackAbove(gfx::NativeView native_view) { 507 native_widget_->StackAbove(native_view); 508} 509 510void Widget::StackAtTop() { 511 native_widget_->StackAtTop(); 512} 513 514void Widget::StackBelow(gfx::NativeView native_view) { 515 native_widget_->StackBelow(native_view); 516} 517 518void Widget::SetShape(gfx::NativeRegion shape) { 519 native_widget_->SetShape(shape); 520} 521 522void Widget::Close() { 523 if (widget_closed_) { 524 // It appears we can hit this code path if you close a modal dialog then 525 // close the last browser before the destructor is hit, which triggers 526 // invoking Close again. 527 return; 528 } 529 530 bool can_close = true; 531 if (non_client_view_) 532 can_close = non_client_view_->CanClose(); 533 if (can_close) { 534 SaveWindowPlacement(); 535 536 // During tear-down the top-level focus manager becomes unavailable to 537 // GTK tabbed panes and their children, so normal deregistration via 538 // |FormManager::ViewRemoved()| calls are fouled. We clear focus here 539 // to avoid these redundant steps and to avoid accessing deleted views 540 // that may have been in focus. 541 if (is_top_level() && focus_manager_.get()) 542 focus_manager_->SetFocusedView(NULL); 543 544 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetClosing(this)); 545 native_widget_->Close(); 546 widget_closed_ = true; 547 } 548} 549 550void Widget::CloseNow() { 551 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetClosing(this)); 552 native_widget_->CloseNow(); 553} 554 555void Widget::Show() { 556 TRACE_EVENT0("views", "Widget::Show"); 557 if (non_client_view_) { 558#if defined(OS_MACOSX) 559 // On the Mac the FullScreenBookmarkBar test is different then for any other 560 // OS. Since the new maximize logic from ash does not apply to the mac, we 561 // continue to ignore the fullscreen mode here. 562 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED && 563 !initial_restored_bounds_.IsEmpty()) { 564 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_); 565 } else { 566 native_widget_->ShowWithWindowState(saved_show_state_); 567 } 568#else 569 // While initializing, the kiosk mode will go to full screen before the 570 // widget gets shown. In that case we stay in full screen mode, regardless 571 // of the |saved_show_state_| member. 572 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED && 573 !initial_restored_bounds_.IsEmpty() && 574 !IsFullscreen()) { 575 native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_); 576 } else { 577 native_widget_->ShowWithWindowState( 578 IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN : saved_show_state_); 579 } 580#endif 581 // |saved_show_state_| only applies the first time the window is shown. 582 // If we don't reset the value the window may be shown maximized every time 583 // it is subsequently shown after being hidden. 584 saved_show_state_ = ui::SHOW_STATE_NORMAL; 585 } else { 586 native_widget_->Show(); 587 } 588} 589 590void Widget::Hide() { 591 native_widget_->Hide(); 592} 593 594void Widget::ShowInactive() { 595 // If this gets called with saved_show_state_ == ui::SHOW_STATE_MAXIMIZED, 596 // call SetBounds()with the restored bounds to set the correct size. This 597 // normally should not happen, but if it does we should avoid showing unsized 598 // windows. 599 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED && 600 !initial_restored_bounds_.IsEmpty()) { 601 SetBounds(initial_restored_bounds_); 602 saved_show_state_ = ui::SHOW_STATE_NORMAL; 603 } 604 native_widget_->ShowWithWindowState(ui::SHOW_STATE_INACTIVE); 605} 606 607void Widget::Activate() { 608 native_widget_->Activate(); 609} 610 611void Widget::Deactivate() { 612 native_widget_->Deactivate(); 613} 614 615bool Widget::IsActive() const { 616 return native_widget_->IsActive(); 617} 618 619void Widget::DisableInactiveRendering() { 620 SetInactiveRenderingDisabled(true); 621} 622 623void Widget::SetAlwaysOnTop(bool on_top) { 624 native_widget_->SetAlwaysOnTop(on_top); 625} 626 627void Widget::Maximize() { 628 native_widget_->Maximize(); 629} 630 631void Widget::Minimize() { 632 native_widget_->Minimize(); 633} 634 635void Widget::Restore() { 636 native_widget_->Restore(); 637} 638 639bool Widget::IsMaximized() const { 640 return native_widget_->IsMaximized(); 641} 642 643bool Widget::IsMinimized() const { 644 return native_widget_->IsMinimized(); 645} 646 647void Widget::SetFullscreen(bool fullscreen) { 648 native_widget_->SetFullscreen(fullscreen); 649} 650 651bool Widget::IsFullscreen() const { 652 return native_widget_->IsFullscreen(); 653} 654 655void Widget::SetOpacity(unsigned char opacity) { 656 native_widget_->SetOpacity(opacity); 657} 658 659void Widget::SetUseDragFrame(bool use_drag_frame) { 660 native_widget_->SetUseDragFrame(use_drag_frame); 661} 662 663void Widget::FlashFrame(bool flash) { 664 native_widget_->FlashFrame(flash); 665} 666 667View* Widget::GetRootView() { 668 return root_view_.get(); 669} 670 671const View* Widget::GetRootView() const { 672 return root_view_.get(); 673} 674 675bool Widget::IsVisible() const { 676 return native_widget_->IsVisible(); 677} 678 679ui::ThemeProvider* Widget::GetThemeProvider() const { 680 const Widget* root_widget = GetTopLevelWidget(); 681 if (root_widget && root_widget != this) { 682 // Attempt to get the theme provider, and fall back to the default theme 683 // provider if not found. 684 ui::ThemeProvider* provider = root_widget->GetThemeProvider(); 685 if (provider) 686 return provider; 687 688 provider = root_widget->default_theme_provider_.get(); 689 if (provider) 690 return provider; 691 } 692 return default_theme_provider_.get(); 693} 694 695const ui::NativeTheme* Widget::GetNativeTheme() const { 696 return native_widget_->GetNativeTheme(); 697} 698 699FocusManager* Widget::GetFocusManager() { 700 Widget* toplevel_widget = GetTopLevelWidget(); 701 return toplevel_widget ? toplevel_widget->focus_manager_.get() : NULL; 702} 703 704const FocusManager* Widget::GetFocusManager() const { 705 const Widget* toplevel_widget = GetTopLevelWidget(); 706 return toplevel_widget ? toplevel_widget->focus_manager_.get() : NULL; 707} 708 709InputMethod* Widget::GetInputMethod() { 710 if (is_top_level()) { 711 if (!input_method_.get()) { 712 input_method_.reset(native_widget_->CreateInputMethod()); 713 if (input_method_.get()) 714 input_method_->Init(this); 715 } 716 return input_method_.get(); 717 } else { 718 Widget* toplevel = GetTopLevelWidget(); 719 // If GetTopLevelWidget() returns itself which is not toplevel, 720 // the widget is detached from toplevel widget. 721 // TODO(oshima): Fix GetTopLevelWidget() to return NULL 722 // if there is no toplevel. We probably need to add GetTopMostWidget() 723 // to replace some use cases. 724 return (toplevel && toplevel != this) ? toplevel->GetInputMethod() : NULL; 725 } 726} 727 728void Widget::RunShellDrag(View* view, 729 const ui::OSExchangeData& data, 730 const gfx::Point& location, 731 int operation, 732 ui::DragDropTypes::DragEventSource source) { 733 dragged_view_ = view; 734 native_widget_->RunShellDrag(view, data, location, operation, source); 735 // If the view is removed during the drag operation, dragged_view_ is set to 736 // NULL. 737 if (view && dragged_view_ == view) { 738 dragged_view_ = NULL; 739 view->OnDragDone(); 740 } 741} 742 743void Widget::SchedulePaintInRect(const gfx::Rect& rect) { 744 native_widget_->SchedulePaintInRect(rect); 745} 746 747void Widget::SetCursor(gfx::NativeCursor cursor) { 748 native_widget_->SetCursor(cursor); 749} 750 751bool Widget::IsMouseEventsEnabled() const { 752 return native_widget_->IsMouseEventsEnabled(); 753} 754 755void Widget::SetNativeWindowProperty(const char* name, void* value) { 756 native_widget_->SetNativeWindowProperty(name, value); 757} 758 759void* Widget::GetNativeWindowProperty(const char* name) const { 760 return native_widget_->GetNativeWindowProperty(name); 761} 762 763void Widget::UpdateWindowTitle() { 764 if (!non_client_view_) 765 return; 766 767 // Update the native frame's text. We do this regardless of whether or not 768 // the native frame is being used, since this also updates the taskbar, etc. 769 string16 window_title = widget_delegate_->GetWindowTitle(); 770 base::i18n::AdjustStringForLocaleDirection(&window_title); 771 native_widget_->SetWindowTitle(window_title); 772 non_client_view_->UpdateWindowTitle(); 773 774 // If the non-client view is rendering its own title, it'll need to relayout 775 // now and to get a paint update later on. 776 non_client_view_->Layout(); 777} 778 779void Widget::UpdateWindowIcon() { 780 if (non_client_view_) 781 non_client_view_->UpdateWindowIcon(); 782 native_widget_->SetWindowIcons(widget_delegate_->GetWindowIcon(), 783 widget_delegate_->GetWindowAppIcon()); 784} 785 786FocusTraversable* Widget::GetFocusTraversable() { 787 return static_cast<internal::RootView*>(root_view_.get()); 788} 789 790void Widget::ThemeChanged() { 791 root_view_->ThemeChanged(); 792} 793 794void Widget::LocaleChanged() { 795 root_view_->LocaleChanged(); 796} 797 798void Widget::SetFocusTraversableParent(FocusTraversable* parent) { 799 root_view_->SetFocusTraversableParent(parent); 800} 801 802void Widget::SetFocusTraversableParentView(View* parent_view) { 803 root_view_->SetFocusTraversableParentView(parent_view); 804} 805 806void Widget::ClearNativeFocus() { 807 native_widget_->ClearNativeFocus(); 808} 809 810NonClientFrameView* Widget::CreateNonClientFrameView() { 811 NonClientFrameView* frame_view = 812 widget_delegate_->CreateNonClientFrameView(this); 813 if (!frame_view) 814 frame_view = native_widget_->CreateNonClientFrameView(); 815 if (!frame_view && ViewsDelegate::views_delegate) { 816 frame_view = 817 ViewsDelegate::views_delegate->CreateDefaultNonClientFrameView(this); 818 } 819 if (frame_view) 820 return frame_view; 821 822 CustomFrameView* custom_frame_view = new CustomFrameView; 823 custom_frame_view->Init(this); 824 return custom_frame_view; 825} 826 827bool Widget::ShouldUseNativeFrame() const { 828 if (frame_type_ != FRAME_TYPE_DEFAULT) 829 return frame_type_ == FRAME_TYPE_FORCE_NATIVE; 830 return native_widget_->ShouldUseNativeFrame(); 831} 832 833void Widget::DebugToggleFrameType() { 834 if (frame_type_ == FRAME_TYPE_DEFAULT) { 835 frame_type_ = ShouldUseNativeFrame() ? FRAME_TYPE_FORCE_CUSTOM : 836 FRAME_TYPE_FORCE_NATIVE; 837 } else { 838 frame_type_ = frame_type_ == FRAME_TYPE_FORCE_CUSTOM ? 839 FRAME_TYPE_FORCE_NATIVE : FRAME_TYPE_FORCE_CUSTOM; 840 } 841 FrameTypeChanged(); 842} 843 844void Widget::FrameTypeChanged() { 845 native_widget_->FrameTypeChanged(); 846} 847 848const ui::Compositor* Widget::GetCompositor() const { 849 return native_widget_->GetCompositor(); 850} 851 852ui::Compositor* Widget::GetCompositor() { 853 return native_widget_->GetCompositor(); 854} 855 856ui::Layer* Widget::GetLayer() { 857 return native_widget_->GetLayer(); 858} 859 860void Widget::ReorderNativeViews() { 861 native_widget_->ReorderNativeViews(); 862} 863 864void Widget::UpdateRootLayers() { 865 // Calculate the layers requires traversing the tree, and since nearly any 866 // mutation of the tree can trigger this call we delay until absolutely 867 // necessary. 868 root_layers_dirty_ = true; 869} 870 871const NativeWidget* Widget::native_widget() const { 872 return native_widget_; 873} 874 875NativeWidget* Widget::native_widget() { 876 return native_widget_; 877} 878 879void Widget::SetCapture(View* view) { 880 if (internal::NativeWidgetPrivate::IsMouseButtonDown()) 881 is_mouse_button_pressed_ = true; 882 if (internal::NativeWidgetPrivate::IsTouchDown()) 883 is_touch_down_ = true; 884 root_view_->SetMouseHandler(view); 885 if (!native_widget_->HasCapture()) 886 native_widget_->SetCapture(); 887} 888 889void Widget::ReleaseCapture() { 890 if (native_widget_->HasCapture()) 891 native_widget_->ReleaseCapture(); 892} 893 894bool Widget::HasCapture() { 895 return native_widget_->HasCapture(); 896} 897 898void Widget::TooltipTextChanged(View* view) { 899 TooltipManager* manager = native_widget_private()->GetTooltipManager(); 900 if (manager) 901 manager->TooltipTextChanged(view); 902} 903 904bool Widget::SetInitialFocus() { 905 View* v = widget_delegate_->GetInitiallyFocusedView(); 906 if (!focus_on_creation_) { 907 // If not focusing the window now, tell the focus manager which view to 908 // focus when the window is restored. 909 if (v) 910 focus_manager_->SetStoredFocusView(v); 911 return true; 912 } 913 if (v) 914 v->RequestFocus(); 915 return !!v; 916} 917 918View* Widget::GetChildViewParent() { 919 return GetContentsView() ? GetContentsView() : GetRootView(); 920} 921 922gfx::Rect Widget::GetWorkAreaBoundsInScreen() const { 923 return native_widget_->GetWorkAreaBoundsInScreen(); 924} 925 926void Widget::SynthesizeMouseMoveEvent() { 927 last_mouse_event_was_move_ = false; 928 ui::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, 929 last_mouse_event_position_, 930 last_mouse_event_position_, 931 ui::EF_IS_SYNTHESIZED); 932 root_view_->OnMouseMoved(mouse_event); 933} 934 935void Widget::OnOwnerClosing() { 936} 937 938//////////////////////////////////////////////////////////////////////////////// 939// Widget, NativeWidgetDelegate implementation: 940 941bool Widget::IsModal() const { 942 return widget_delegate_->GetModalType() != ui::MODAL_TYPE_NONE; 943} 944 945bool Widget::IsDialogBox() const { 946 return !!widget_delegate_->AsDialogDelegate(); 947} 948 949bool Widget::CanActivate() const { 950 return widget_delegate_->CanActivate(); 951} 952 953bool Widget::IsInactiveRenderingDisabled() const { 954 return disable_inactive_rendering_; 955} 956 957void Widget::EnableInactiveRendering() { 958 SetInactiveRenderingDisabled(false); 959} 960 961void Widget::OnNativeWidgetActivationChanged(bool active) { 962 // On windows we may end up here before we've completed initialization (from 963 // an WM_NCACTIVATE). If that happens the WidgetDelegate likely doesn't know 964 // the Widget and will crash attempting to access it. 965 if (!active && native_widget_initialized_) 966 SaveWindowPlacement(); 967 968 FOR_EACH_OBSERVER(WidgetObserver, observers_, 969 OnWidgetActivationChanged(this, active)); 970} 971 972void Widget::OnNativeFocus(gfx::NativeView old_focused_view) { 973 WidgetFocusManager::GetInstance()->OnWidgetFocusEvent(old_focused_view, 974 GetNativeView()); 975} 976 977void Widget::OnNativeBlur(gfx::NativeView new_focused_view) { 978 WidgetFocusManager::GetInstance()->OnWidgetFocusEvent(GetNativeView(), 979 new_focused_view); 980} 981 982void Widget::OnNativeWidgetVisibilityChanged(bool visible) { 983 View* root = GetRootView(); 984 if (root) 985 root->PropagateVisibilityNotifications(root, visible); 986 FOR_EACH_OBSERVER(WidgetObserver, observers_, 987 OnWidgetVisibilityChanged(this, visible)); 988 if (GetCompositor() && root && root->layer()) 989 root->layer()->SetVisible(visible); 990} 991 992void Widget::OnNativeWidgetCreated(bool desktop_widget) { 993 if (is_top_level()) 994 focus_manager_.reset(FocusManagerFactory::Create(this, desktop_widget)); 995 996 native_widget_->InitModalType(widget_delegate_->GetModalType()); 997 998 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetCreated(this)); 999} 1000 1001void Widget::OnNativeWidgetDestroying() { 1002 // Tell the focus manager (if any) that root_view is being removed 1003 // in case that the focused view is under this root view. 1004 if (GetFocusManager()) 1005 GetFocusManager()->ViewRemoved(root_view_.get()); 1006 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetDestroying(this)); 1007 if (non_client_view_) 1008 non_client_view_->WindowClosing(); 1009 widget_delegate_->WindowClosing(); 1010} 1011 1012void Widget::OnNativeWidgetDestroyed() { 1013 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetDestroyed(this)); 1014 widget_delegate_->DeleteDelegate(); 1015 widget_delegate_ = NULL; 1016 native_widget_destroyed_ = true; 1017} 1018 1019gfx::Size Widget::GetMinimumSize() { 1020 return non_client_view_ ? non_client_view_->GetMinimumSize() : gfx::Size(); 1021} 1022 1023gfx::Size Widget::GetMaximumSize() { 1024 return non_client_view_ ? non_client_view_->GetMaximumSize() : gfx::Size(); 1025} 1026 1027void Widget::OnNativeWidgetMove() { 1028 widget_delegate_->OnWidgetMove(); 1029 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetBoundsChanged( 1030 this, 1031 GetWindowBoundsInScreen())); 1032} 1033 1034void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) { 1035 root_view_->SetSize(new_size); 1036 1037 // Size changed notifications can fire prior to full initialization 1038 // i.e. during session restore. Avoid saving session state during these 1039 // startup procedures. 1040 if (native_widget_initialized_) 1041 SaveWindowPlacement(); 1042 1043 FOR_EACH_OBSERVER(WidgetObserver, observers_, OnWidgetBoundsChanged( 1044 this, 1045 GetWindowBoundsInScreen())); 1046} 1047 1048void Widget::OnNativeWidgetBeginUserBoundsChange() { 1049 widget_delegate_->OnWindowBeginUserBoundsChange(); 1050} 1051 1052void Widget::OnNativeWidgetEndUserBoundsChange() { 1053 widget_delegate_->OnWindowEndUserBoundsChange(); 1054} 1055 1056bool Widget::HasFocusManager() const { 1057 return !!focus_manager_.get(); 1058} 1059 1060bool Widget::OnNativeWidgetPaintAccelerated(const gfx::Rect& dirty_region) { 1061 ui::Compositor* compositor = GetCompositor(); 1062 if (!compositor) 1063 return false; 1064 1065 compositor->ScheduleRedrawRect(dirty_region); 1066 return true; 1067} 1068 1069void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { 1070 // On Linux Aura, we can get here during Init() because of the 1071 // SetInitialBounds call. 1072 if (native_widget_initialized_) 1073 GetRootView()->Paint(canvas); 1074} 1075 1076int Widget::GetNonClientComponent(const gfx::Point& point) { 1077 int component = non_client_view_ ? 1078 non_client_view_->NonClientHitTest(point) : 1079 HTNOWHERE; 1080 1081 if (movement_disabled_ && (component == HTCAPTION || component == HTSYSMENU)) 1082 return HTNOWHERE; 1083 1084 return component; 1085} 1086 1087void Widget::OnKeyEvent(ui::KeyEvent* event) { 1088 static_cast<internal::RootView*>(GetRootView())-> 1089 DispatchKeyEvent(event); 1090} 1091 1092void Widget::OnMouseEvent(ui::MouseEvent* event) { 1093 if (!IsMouseEventsEnabled()) 1094 return; 1095 1096 View* root_view = GetRootView(); 1097 switch (event->type()) { 1098 case ui::ET_MOUSE_PRESSED: { 1099 last_mouse_event_was_move_ = false; 1100 1101 // We may get deleted by the time we return from OnMousePressed. So we 1102 // use an observer to make sure we are still alive. 1103 WidgetDeletionObserver widget_deletion_observer(this); 1104 // Make sure we're still visible before we attempt capture as the mouse 1105 // press processing may have made the window hide (as happens with menus). 1106 if (root_view && root_view->OnMousePressed(*event) && 1107 widget_deletion_observer.IsWidgetAlive() && IsVisible()) { 1108 is_mouse_button_pressed_ = true; 1109 if (!native_widget_->HasCapture()) 1110 native_widget_->SetCapture(); 1111 event->SetHandled(); 1112 } 1113 return; 1114 } 1115 case ui::ET_MOUSE_RELEASED: 1116 last_mouse_event_was_move_ = false; 1117 is_mouse_button_pressed_ = false; 1118 // Release capture first, to avoid confusion if OnMouseReleased blocks. 1119 if (native_widget_->HasCapture() && 1120 ShouldReleaseCaptureOnMouseReleased()) { 1121 native_widget_->ReleaseCapture(); 1122 } 1123 if (root_view) 1124 root_view->OnMouseReleased(*event); 1125 if ((event->flags() & ui::EF_IS_NON_CLIENT) == 0) 1126 event->SetHandled(); 1127 return; 1128 case ui::ET_MOUSE_MOVED: 1129 case ui::ET_MOUSE_DRAGGED: 1130 if (native_widget_->HasCapture() && is_mouse_button_pressed_) { 1131 last_mouse_event_was_move_ = false; 1132 if (root_view) 1133 root_view->OnMouseDragged(*event); 1134 } else if (!last_mouse_event_was_move_ || 1135 last_mouse_event_position_ != event->location()) { 1136 last_mouse_event_position_ = event->location(); 1137 last_mouse_event_was_move_ = true; 1138 if (root_view) 1139 root_view->OnMouseMoved(*event); 1140 } 1141 return; 1142 case ui::ET_MOUSE_EXITED: 1143 last_mouse_event_was_move_ = false; 1144 if (root_view) 1145 root_view->OnMouseExited(*event); 1146 return; 1147 case ui::ET_MOUSEWHEEL: 1148 if (root_view && root_view->OnMouseWheel( 1149 static_cast<const ui::MouseWheelEvent&>(*event))) 1150 event->SetHandled(); 1151 return; 1152 default: 1153 return; 1154 } 1155 event->SetHandled(); 1156} 1157 1158void Widget::OnMouseCaptureLost() { 1159 if (is_mouse_button_pressed_ || is_touch_down_) { 1160 View* root_view = GetRootView(); 1161 if (root_view) 1162 root_view->OnMouseCaptureLost(); 1163 } 1164 is_touch_down_ = false; 1165 is_mouse_button_pressed_ = false; 1166} 1167 1168void Widget::OnTouchEvent(ui::TouchEvent* event) { 1169 static_cast<internal::RootView*>(GetRootView())-> 1170 DispatchTouchEvent(event); 1171} 1172 1173void Widget::OnScrollEvent(ui::ScrollEvent* event) { 1174 static_cast<internal::RootView*>(GetRootView())-> 1175 DispatchScrollEvent(event); 1176} 1177 1178void Widget::OnGestureEvent(ui::GestureEvent* event) { 1179 switch (event->type()) { 1180 case ui::ET_GESTURE_TAP_DOWN: 1181 is_touch_down_ = true; 1182 // We explicitly don't capture here. Not capturing enables multiple 1183 // widgets to get tap events at the same time. Views (such as tab 1184 // dragging) may explicitly capture. 1185 break; 1186 1187 case ui::ET_GESTURE_END: 1188 if (event->details().touch_points() == 1) { 1189 is_touch_down_ = false; 1190 if (ShouldReleaseCaptureOnMouseReleased()) 1191 ReleaseCapture(); 1192 } 1193 break; 1194 1195 default: 1196 break; 1197 } 1198 static_cast<internal::RootView*>(GetRootView())->DispatchGestureEvent(event); 1199} 1200 1201bool Widget::ExecuteCommand(int command_id) { 1202 return widget_delegate_->ExecuteWindowsCommand(command_id); 1203} 1204 1205InputMethod* Widget::GetInputMethodDirect() { 1206 return input_method_.get(); 1207} 1208 1209const std::vector<ui::Layer*>& Widget::GetRootLayers() { 1210 if (root_layers_dirty_) { 1211 root_layers_dirty_ = false; 1212 root_layers_.clear(); 1213 BuildRootLayers(GetRootView(), &root_layers_); 1214 } 1215 return root_layers_; 1216} 1217 1218bool Widget::HasHitTestMask() const { 1219 return widget_delegate_->WidgetHasHitTestMask(); 1220} 1221 1222void Widget::GetHitTestMask(gfx::Path* mask) const { 1223 DCHECK(mask); 1224 widget_delegate_->GetWidgetHitTestMask(mask); 1225} 1226 1227Widget* Widget::AsWidget() { 1228 return this; 1229} 1230 1231const Widget* Widget::AsWidget() const { 1232 return this; 1233} 1234 1235//////////////////////////////////////////////////////////////////////////////// 1236// Widget, FocusTraversable implementation: 1237 1238FocusSearch* Widget::GetFocusSearch() { 1239 return root_view_->GetFocusSearch(); 1240} 1241 1242FocusTraversable* Widget::GetFocusTraversableParent() { 1243 // We are a proxy to the root view, so we should be bypassed when traversing 1244 // up and as a result this should not be called. 1245 NOTREACHED(); 1246 return NULL; 1247} 1248 1249View* Widget::GetFocusTraversableParentView() { 1250 // We are a proxy to the root view, so we should be bypassed when traversing 1251 // up and as a result this should not be called. 1252 NOTREACHED(); 1253 return NULL; 1254} 1255 1256//////////////////////////////////////////////////////////////////////////////// 1257// Widget, protected: 1258 1259internal::RootView* Widget::CreateRootView() { 1260 return new internal::RootView(this); 1261} 1262 1263void Widget::DestroyRootView() { 1264 non_client_view_ = NULL; 1265 root_view_.reset(); 1266 // Input method has to be destroyed before focus manager. 1267 input_method_.reset(); 1268} 1269 1270//////////////////////////////////////////////////////////////////////////////// 1271// Widget, private: 1272 1273bool Widget::ShouldReleaseCaptureOnMouseReleased() const { 1274 return true; 1275} 1276 1277void Widget::SetInactiveRenderingDisabled(bool value) { 1278 if (value == disable_inactive_rendering_) 1279 return; 1280 1281 disable_inactive_rendering_ = value; 1282 if (non_client_view_) 1283 non_client_view_->SetInactiveRenderingDisabled(value); 1284 native_widget_->SetInactiveRenderingDisabled(value); 1285} 1286 1287void Widget::SaveWindowPlacement() { 1288 // The window delegate does the actual saving for us. It seems like (judging 1289 // by go/crash) that in some circumstances we can end up here after 1290 // WM_DESTROY, at which point the window delegate is likely gone. So just 1291 // bail. 1292 if (!widget_delegate_) 1293 return; 1294 1295 ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL; 1296 gfx::Rect bounds; 1297 native_widget_->GetWindowPlacement(&bounds, &show_state); 1298 widget_delegate_->SaveWindowPlacement(bounds, show_state); 1299} 1300 1301void Widget::SetInitialBounds(const gfx::Rect& bounds) { 1302 if (!non_client_view_) 1303 return; 1304 1305 gfx::Rect saved_bounds; 1306 if (GetSavedWindowPlacement(&saved_bounds, &saved_show_state_)) { 1307 if (saved_show_state_ == ui::SHOW_STATE_MAXIMIZED) { 1308 // If we're going to maximize, wait until Show is invoked to set the 1309 // bounds. That way we avoid a noticeable resize. 1310 initial_restored_bounds_ = saved_bounds; 1311 } else if (!saved_bounds.IsEmpty()) { 1312 // If the saved bounds are valid, use them. 1313 SetBounds(saved_bounds); 1314 } 1315 } else { 1316 if (bounds.IsEmpty()) { 1317 // No initial bounds supplied, so size the window to its content and 1318 // center over its parent. 1319 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); 1320 } else { 1321 // Use the supplied initial bounds. 1322 SetBoundsConstrained(bounds); 1323 } 1324 } 1325} 1326 1327void Widget::SetInitialBoundsForFramelessWindow(const gfx::Rect& bounds) { 1328 if (bounds.IsEmpty()) { 1329 View* contents_view = GetContentsView(); 1330 DCHECK(contents_view); 1331 // No initial bounds supplied, so size the window to its content and 1332 // center over its parent if preferred size is provided. 1333 gfx::Size size = contents_view->GetPreferredSize(); 1334 if (!size.IsEmpty()) 1335 native_widget_->CenterWindow(size); 1336 } else { 1337 // Use the supplied initial bounds. 1338 SetBoundsConstrained(bounds); 1339 } 1340} 1341 1342bool Widget::GetSavedWindowPlacement(gfx::Rect* bounds, 1343 ui::WindowShowState* show_state) { 1344 // First we obtain the window's saved show-style and store it. We need to do 1345 // this here, rather than in Show() because by the time Show() is called, 1346 // the window's size will have been reset (below) and the saved maximized 1347 // state will have been lost. Sadly there's no way to tell on Windows when 1348 // a window is restored from maximized state, so we can't more accurately 1349 // track maximized state independently of sizing information. 1350 1351 // Restore the window's placement from the controller. 1352 if (widget_delegate_->GetSavedWindowPlacement(bounds, show_state)) { 1353 if (!widget_delegate_->ShouldRestoreWindowSize()) { 1354 bounds->set_size(non_client_view_->GetPreferredSize()); 1355 } else { 1356 gfx::Size minimum_size = GetMinimumSize(); 1357 // Make sure the bounds are at least the minimum size. 1358 if (bounds->width() < minimum_size.width()) 1359 bounds->set_width(minimum_size.width()); 1360 1361 if (bounds->height() < minimum_size.height()) 1362 bounds->set_height(minimum_size.height()); 1363 } 1364 return true; 1365 } 1366 return false; 1367} 1368 1369void Widget::ReplaceInputMethod(InputMethod* input_method) { 1370 input_method_.reset(input_method); 1371 input_method->SetDelegate(native_widget_->GetInputMethodDelegate()); 1372 input_method->Init(this); 1373} 1374 1375namespace internal { 1376 1377//////////////////////////////////////////////////////////////////////////////// 1378// internal::NativeWidgetPrivate, NativeWidget implementation: 1379 1380internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { 1381 return this; 1382} 1383 1384} // namespace internal 1385} // namespace views 1386