1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/xul/nsTitleBarFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,172 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsCOMPtr.h" 1.10 +#include "nsTitleBarFrame.h" 1.11 +#include "nsIContent.h" 1.12 +#include "nsIDocument.h" 1.13 +#include "nsIDOMNodeList.h" 1.14 +#include "nsGkAtoms.h" 1.15 +#include "nsIWidget.h" 1.16 +#include "nsMenuPopupFrame.h" 1.17 +#include "nsPresContext.h" 1.18 +#include "nsIDocShell.h" 1.19 +#include "nsPIDOMWindow.h" 1.20 +#include "nsDisplayList.h" 1.21 +#include "nsContentUtils.h" 1.22 +#include "mozilla/MouseEvents.h" 1.23 + 1.24 +using namespace mozilla; 1.25 + 1.26 +// 1.27 +// NS_NewTitleBarFrame 1.28 +// 1.29 +// Creates a new TitleBar frame and returns it 1.30 +// 1.31 +nsIFrame* 1.32 +NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) 1.33 +{ 1.34 + return new (aPresShell) nsTitleBarFrame(aPresShell, aContext); 1.35 +} 1.36 + 1.37 +NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame) 1.38 + 1.39 +nsTitleBarFrame::nsTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) 1.40 +:nsBoxFrame(aPresShell, aContext, false) 1.41 +{ 1.42 + mTrackingMouseMove = false; 1.43 + UpdateMouseThrough(); 1.44 +} 1.45 + 1.46 +void 1.47 +nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, 1.48 + const nsRect& aDirtyRect, 1.49 + const nsDisplayListSet& aLists) 1.50 +{ 1.51 + // override, since we don't want children to get events 1.52 + if (aBuilder->IsForEventDelivery()) { 1.53 + if (!mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents, 1.54 + nsGkAtoms::_true, eCaseMatters)) 1.55 + return; 1.56 + } 1.57 + nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists); 1.58 +} 1.59 + 1.60 +nsresult 1.61 +nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext, 1.62 + WidgetGUIEvent* aEvent, 1.63 + nsEventStatus* aEventStatus) 1.64 +{ 1.65 + NS_ENSURE_ARG_POINTER(aEventStatus); 1.66 + if (nsEventStatus_eConsumeNoDefault == *aEventStatus) { 1.67 + return NS_OK; 1.68 + } 1.69 + 1.70 + bool doDefault = true; 1.71 + 1.72 + switch (aEvent->message) { 1.73 + 1.74 + case NS_MOUSE_BUTTON_DOWN: { 1.75 + if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { 1.76 + // titlebar has no effect in non-chrome shells 1.77 + nsCOMPtr<nsIDocShellTreeItem> dsti = aPresContext->GetDocShell(); 1.78 + if (dsti) { 1.79 + if (dsti->ItemType() == nsIDocShellTreeItem::typeChrome) { 1.80 + // we're tracking. 1.81 + mTrackingMouseMove = true; 1.82 + 1.83 + // start capture. 1.84 + nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED); 1.85 + 1.86 + // remember current mouse coordinates. 1.87 + mLastPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); 1.88 + } 1.89 + } 1.90 + 1.91 + *aEventStatus = nsEventStatus_eConsumeNoDefault; 1.92 + doDefault = false; 1.93 + } 1.94 + } 1.95 + break; 1.96 + 1.97 + 1.98 + case NS_MOUSE_BUTTON_UP: { 1.99 + if (mTrackingMouseMove && 1.100 + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { 1.101 + // we're done tracking. 1.102 + mTrackingMouseMove = false; 1.103 + 1.104 + // end capture 1.105 + nsIPresShell::SetCapturingContent(nullptr, 0); 1.106 + 1.107 + *aEventStatus = nsEventStatus_eConsumeNoDefault; 1.108 + doDefault = false; 1.109 + } 1.110 + } 1.111 + break; 1.112 + 1.113 + case NS_MOUSE_MOVE: { 1.114 + if(mTrackingMouseMove) 1.115 + { 1.116 + nsIntPoint nsMoveBy = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint) - mLastPoint; 1.117 + 1.118 + nsIFrame* parent = GetParent(); 1.119 + while (parent) { 1.120 + nsMenuPopupFrame* popupFrame = do_QueryFrame(parent); 1.121 + if (popupFrame) 1.122 + break; 1.123 + parent = parent->GetParent(); 1.124 + } 1.125 + 1.126 + // if the titlebar is in a popup, move the popup frame, otherwise 1.127 + // move the widget associated with the window 1.128 + if (parent) { 1.129 + nsMenuPopupFrame* menuPopupFrame = static_cast<nsMenuPopupFrame*>(parent); 1.130 + nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget(); 1.131 + nsIntRect bounds; 1.132 + widget->GetScreenBounds(bounds); 1.133 + 1.134 + int32_t newx = aPresContext->DevPixelsToIntCSSPixels(bounds.x + nsMoveBy.x); 1.135 + int32_t newy = aPresContext->DevPixelsToIntCSSPixels(bounds.y + nsMoveBy.y); 1.136 + menuPopupFrame->MoveTo(newx, newy, false); 1.137 + } 1.138 + else { 1.139 + nsIPresShell* presShell = aPresContext->PresShell(); 1.140 + nsPIDOMWindow *window = presShell->GetDocument()->GetWindow(); 1.141 + if (window) { 1.142 + window->MoveBy(nsMoveBy.x, nsMoveBy.y); 1.143 + } 1.144 + } 1.145 + 1.146 + *aEventStatus = nsEventStatus_eConsumeNoDefault; 1.147 + 1.148 + doDefault = false; 1.149 + } 1.150 + } 1.151 + break; 1.152 + 1.153 + case NS_MOUSE_CLICK: { 1.154 + WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent(); 1.155 + if (mouseEvent->IsLeftClickEvent()) { 1.156 + MouseClicked(aPresContext, mouseEvent); 1.157 + } 1.158 + break; 1.159 + } 1.160 + } 1.161 + 1.162 + if ( doDefault ) 1.163 + return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); 1.164 + else 1.165 + return NS_OK; 1.166 +} 1.167 + 1.168 +void 1.169 +nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, 1.170 + WidgetMouseEvent* aEvent) 1.171 +{ 1.172 + // Execute the oncommand event handler. 1.173 + nsContentUtils::DispatchXULCommand(mContent, 1.174 + aEvent && aEvent->mFlags.mIsTrusted); 1.175 +}