15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/non_client_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/rect_conversions.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/rect_based_targeting_utils.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/root_view.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/client_view.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char NonClientFrameView::kViewClassName[] = 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ui/views/window/NonClientFrameView"; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char NonClientView::kViewClassName[] = 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ui/views/window/NonClientView"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The frame view and the client view are always at these specific indices, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because the RootView message dispatch sends messages to items higher in the 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// z-order first and we always want the client view to have first crack at 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// handling mouse messages. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kFrameViewIndex = 0; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kClientViewIndex = 1; 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The overlay view is always on top (index == child_count() - 1). 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NonClientView, public: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NonClientView::NonClientView() 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : client_view_(NULL), 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) overlay_view_(NULL) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NonClientView::~NonClientView() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This value may have been reset before the window hierarchy shuts down, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we need to manually remove it. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(frame_view_.get()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::SetFrameView(NonClientFrameView* frame_view) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See comment in header about ownership. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view->set_owned_by_client(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame_view_.get()) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveChildView(frame_view_.get()); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_.reset(frame_view); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent()) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(frame_view_.get(), kFrameViewIndex); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void NonClientView::SetOverlayView(View* view) { 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (overlay_view_) 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RemoveChildView(overlay_view_); 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!view) 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) overlay_view_ = view; 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (parent()) 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AddChildView(overlay_view_); 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NonClientView::CanClose() { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return client_view_->CanClose(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::WindowClosing() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_view_->WidgetClosing(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void NonClientView::UpdateFrame() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Widget* widget = GetWidget(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetFrameView(widget->CreateNonClientFrameView()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->ThemeChanged(); 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Layout(); 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SchedulePaint(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::SetInactiveRenderingDisabled(bool disable) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->SetInactiveRenderingDisabled(disable); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect NonClientView::GetWindowBoundsForClientBounds( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect client_bounds) const { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_view_->GetWindowBoundsForClientBounds(client_bounds); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NonClientView::NonClientHitTest(const gfx::Point& point) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The NonClientFrameView is responsible for also asking the ClientView. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_view_->NonClientHitTest(point); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::GetWindowMask(const gfx::Size& size, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Path* window_mask) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->GetWindowMask(size, window_mask); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::ResetWindowControls() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->ResetWindowControls(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::UpdateWindowIcon() { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->UpdateWindowIcon(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::UpdateWindowTitle() { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->UpdateWindowTitle(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::LayoutFrameView() { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First layout the NonClientFrameView, which determines the size of the 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientView... 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->SetBounds(0, 0, width(), height()); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to manually call Layout here because layout for the frame view can 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change independently of the bounds changing - e.g. after the initial 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // display of the window the metrics of the native window controls can change, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which does not change the bounds of the window but requires a re-layout to 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // trigger a repaint. We override OnBoundsChanged() for the NonClientFrameView 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to do nothing so that SetBounds above doesn't cause Layout to be called 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // twice. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_view_->Layout(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NonClientView::SetAccessibleName(const base::string16& name) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accessible_name_ = name; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NonClientView, View overrides: 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size NonClientView::GetPreferredSize() const { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(pkasting): This should probably be made to look similar to 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetMinimumSize() below. This will require implementing GetPreferredSize() 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // better in the various frame views. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect client_bounds(gfx::Point(), client_view_->GetPreferredSize()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowBoundsForClientBounds(client_bounds).size(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size NonClientView::GetMinimumSize() const { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_view_->GetMinimumSize(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size NonClientView::GetMaximumSize() const { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_view_->GetMaximumSize(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientView::Layout() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayoutFrameView(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then layout the ClientView, using those bounds. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_view_->SetBoundsRect(frame_view_->GetBoundsForClientView()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to manually call Layout on the ClientView as well for the same 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reason as above. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_view_->Layout(); 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (overlay_view_ && overlay_view_->visible()) 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) overlay_view_->SetBoundsRect(GetLocalBounds()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void NonClientView::ViewHierarchyChanged( 168a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const ViewHierarchyChangedDetails& details) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add our two child views here as we are added to the Widget so that if we 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are subsequently resized all the parent-child relationships are 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // established. 172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (details.is_add && GetWidget() && details.child == this) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(frame_view_.get(), kFrameViewIndex); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddChildViewAt(client_view_, kClientViewIndex); 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (overlay_view_) 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AddChildView(overlay_view_); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NonClientView::GetAccessibleState(ui::AXViewState* state) { 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_CLIENT; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->name = accessible_name_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* NonClientView::GetClassName() const { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochView* NonClientView::GetEventHandlerForRect(const gfx::Rect& rect) { 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!UsePointBasedTargeting(rect)) 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return View::GetEventHandlerForRect(rect); 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because of the z-ordering of our child views (the client view is positioned 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // over the non-client frame view, if the client view ever overlaps the frame 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // view visually (as it does for the browser window), then it will eat 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events for the window controls. We override this method here so that we can 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detect this condition and re-route the events to the non-client frame view. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The assumption is that the frame view's implementation of HitTest will only 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return true for area not occupied by the client view. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame_view_->parent() == this) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // During the reset of the frame_view_ it's possible to be in this code 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after it's been removed from the view hierarchy but before it's been 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // removed from the NonClientView. 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::RectF rect_in_child_coords_f(rect); 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) View::ConvertRectToTarget(this, frame_view_.get(), &rect_in_child_coords_f); 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect rect_in_child_coords = gfx::ToEnclosingRect( 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rect_in_child_coords_f); 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (frame_view_->HitTestRect(rect_in_child_coords)) 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return frame_view_->GetEventHandlerForRect(rect_in_child_coords); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return View::GetEventHandlerForRect(rect); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochView* NonClientView::GetTooltipHandlerForPoint(const gfx::Point& point) { 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The same logic as for |GetEventHandlerForRect()| applies here. 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (frame_view_->parent() == this) { 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // During the reset of the frame_view_ it's possible to be in this code 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // after it's been removed from the view hierarchy but before it's been 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // removed from the NonClientView. 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Point point_in_child_coords(point); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) View::ConvertPointToTarget(this, frame_view_.get(), &point_in_child_coords); 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch View* handler = 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame_view_->GetTooltipHandlerForPoint(point_in_child_coords); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (handler) 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return handler; 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return View::GetTooltipHandlerForPoint(point); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NonClientFrameView, public: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NonClientFrameView::~NonClientFrameView() { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientFrameView::SetInactiveRenderingDisabled(bool disable) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (inactive_rendering_disabled_ == disable) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool should_paint_as_active_old = ShouldPaintAsActive(); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) inactive_rendering_disabled_ = disable; 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The widget schedules a paint when the activation changes. 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (should_paint_as_active_old != ShouldPaintAsActive()) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SchedulePaint(); 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool NonClientFrameView::ShouldPaintAsActive() const { 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return inactive_rendering_disabled_ || GetWidget()->IsActive(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NonClientFrameView::GetHTComponentForFrame(const gfx::Point& point, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top_resize_border_height, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resize_border_thickness, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top_resize_corner_height, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resize_corner_width, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_resize) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tricky: In XP, native behavior is to return HTTOPLEFT and HTTOPRIGHT for 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a |resize_corner_size|-length strip of both the side and top borders, but 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only to return HTBOTTOMLEFT/HTBOTTOMRIGHT along the bottom border + corner 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (not the side border). Vista goes further and doesn't return these on any 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the side borders. We allow callers to match either behavior. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int component; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (point.x() < resize_border_thickness) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (point.y() < top_resize_corner_height) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTTOPLEFT; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (point.y() >= (height() - resize_border_thickness)) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTBOTTOMLEFT; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTLEFT; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (point.x() >= (width() - resize_border_thickness)) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (point.y() < top_resize_corner_height) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTTOPRIGHT; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (point.y() >= (height() - resize_border_thickness)) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTBOTTOMRIGHT; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTRIGHT; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (point.y() < top_resize_border_height) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (point.x() < resize_corner_width) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTTOPLEFT; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (point.x() >= (width() - resize_corner_width)) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTTOPRIGHT; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTTOP; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (point.y() >= (height() - resize_border_thickness)) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (point.x() < resize_corner_width) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTBOTTOMLEFT; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (point.x() >= (width() - resize_corner_width)) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTBOTTOMRIGHT; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component = HTBOTTOM; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HTNOWHERE; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the window can't be resized, there are no resize boundaries, just 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window borders. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return can_resize ? component : HTBORDER; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NonClientFrameView, View overrides: 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NonClientFrameView::HitTestRect(const gfx::Rect& rect) const { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For the default case, we assume the non-client frame view never overlaps 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the client view. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !GetWidget()->client_view()->bounds().Intersects(rect); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NonClientFrameView, protected: 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NonClientFrameView::GetAccessibleState(ui::AXViewState* state) { 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_CLIENT; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* NonClientFrameView::GetClassName() const { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kViewClassName; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NonClientFrameView::OnBoundsChanged(const gfx::Rect& previous_bounds) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Overridden to do nothing. The NonClientView manually calls Layout on the 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FrameView when it is itself laid out, see comment in NonClientView::Layout. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NonClientFrameView::NonClientFrameView() : inactive_rendering_disabled_(false) { 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 332