Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/xul/nsTitleBarFrame.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "nsCOMPtr.h"
8
#include "nsTitleBarFrame.h"
9
#include "nsIContent.h"
10
#include "nsIDocument.h"
11
#include "nsGkAtoms.h"
12
#include "nsIWidget.h"
13
#include "nsMenuPopupFrame.h"
14
#include "nsPresContext.h"
15
#include "nsIDocShell.h"
16
#include "nsPIDOMWindow.h"
17
#include "nsDisplayList.h"
18
#include "nsContentUtils.h"
19
#include "mozilla/MouseEvents.h"
20
#include "mozilla/dom/MouseEventBinding.h"
21
22
using namespace mozilla;
23
24
//
25
// NS_NewTitleBarFrame
26
//
27
// Creates a new TitleBar frame and returns it
28
//
29
nsIFrame*
30
NS_NewTitleBarFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle)
31
0
{
32
0
  return new (aPresShell) nsTitleBarFrame(aStyle);
33
0
}
34
35
NS_IMPL_FRAMEARENA_HELPERS(nsTitleBarFrame)
36
37
nsTitleBarFrame::nsTitleBarFrame(ComputedStyle* aStyle, ClassID aID)
38
  : nsBoxFrame(aStyle, aID, false)
39
0
{
40
0
  mTrackingMouseMove = false;
41
0
  UpdateMouseThrough();
42
0
}
43
44
void
45
nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder*   aBuilder,
46
                                             const nsDisplayListSet& aLists)
47
0
{
48
0
  // override, since we don't want children to get events
49
0
  if (aBuilder->IsForEventDelivery()) {
50
0
    if (!mContent->AsElement()->AttrValueIs(kNameSpaceID_None,
51
0
                                            nsGkAtoms::allowevents,
52
0
                                            nsGkAtoms::_true, eCaseMatters))
53
0
      return;
54
0
  }
55
0
  nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists);
56
0
}
57
58
nsresult
59
nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext,
60
                             WidgetGUIEvent* aEvent,
61
                             nsEventStatus* aEventStatus)
62
0
{
63
0
  NS_ENSURE_ARG_POINTER(aEventStatus);
64
0
  if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
65
0
    return NS_OK;
66
0
  }
67
0
68
0
  bool doDefault = true;
69
0
70
0
  switch (aEvent->mMessage) {
71
0
72
0
   case eMouseDown: {
73
0
       if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
74
0
         // titlebar has no effect in non-chrome shells
75
0
         nsCOMPtr<nsIDocShellTreeItem> dsti = aPresContext->GetDocShell();
76
0
         if (dsti) {
77
0
           if (dsti->ItemType() == nsIDocShellTreeItem::typeChrome) {
78
0
             // we're tracking.
79
0
             mTrackingMouseMove = true;
80
0
81
0
             // start capture.
82
0
             nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
83
0
84
0
             // remember current mouse coordinates.
85
0
             mLastPoint = aEvent->mRefPoint;
86
0
           }
87
0
         }
88
0
89
0
         *aEventStatus = nsEventStatus_eConsumeNoDefault;
90
0
         doDefault = false;
91
0
       }
92
0
     }
93
0
     break;
94
0
95
0
96
0
   case eMouseUp: {
97
0
       if (mTrackingMouseMove &&
98
0
           aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
99
0
         // we're done tracking.
100
0
         mTrackingMouseMove = false;
101
0
102
0
         // end capture
103
0
         nsIPresShell::SetCapturingContent(nullptr, 0);
104
0
105
0
         *aEventStatus = nsEventStatus_eConsumeNoDefault;
106
0
         doDefault = false;
107
0
       }
108
0
     }
109
0
     break;
110
0
111
0
   case eMouseMove: {
112
0
       if(mTrackingMouseMove)
113
0
       {
114
0
         LayoutDeviceIntPoint nsMoveBy = aEvent->mRefPoint - mLastPoint;
115
0
116
0
         nsIFrame* parent = GetParent();
117
0
         while (parent) {
118
0
           nsMenuPopupFrame* popupFrame = do_QueryFrame(parent);
119
0
           if (popupFrame)
120
0
             break;
121
0
           parent = parent->GetParent();
122
0
         }
123
0
124
0
         // if the titlebar is in a popup, move the popup frame, otherwise
125
0
         // move the widget associated with the window
126
0
         if (parent) {
127
0
           nsMenuPopupFrame* menuPopupFrame = static_cast<nsMenuPopupFrame*>(parent);
128
0
           nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget();
129
0
           LayoutDeviceIntRect bounds = widget->GetScreenBounds();
130
0
131
0
           CSSPoint cssPos = (bounds.TopLeft() + nsMoveBy)
132
0
                           / aPresContext->CSSToDevPixelScale();
133
0
           menuPopupFrame->MoveTo(RoundedToInt(cssPos), false);
134
0
         }
135
0
         else {
136
0
           nsIPresShell* presShell = aPresContext->PresShell();
137
0
           nsPIDOMWindowOuter *window = presShell->GetDocument()->GetWindow();
138
0
           if (window) {
139
0
             window->MoveBy(nsMoveBy.x, nsMoveBy.y);
140
0
           }
141
0
         }
142
0
143
0
         *aEventStatus = nsEventStatus_eConsumeNoDefault;
144
0
145
0
         doDefault = false;
146
0
       }
147
0
     }
148
0
     break;
149
0
150
0
    case eMouseClick: {
151
0
      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
152
0
      if (mouseEvent->IsLeftClickEvent()) {
153
0
        MouseClicked(mouseEvent);
154
0
      }
155
0
      break;
156
0
    }
157
0
158
0
    default:
159
0
      break;
160
0
  }
161
0
162
0
  if ( doDefault )
163
0
    return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
164
0
  else
165
0
    return NS_OK;
166
0
}
167
168
void
169
nsTitleBarFrame::MouseClicked(WidgetMouseEvent* aEvent)
170
0
{
171
0
  // Execute the oncommand event handler.
172
0
  nsContentUtils::DispatchXULCommand(mContent, false, nullptr,
173
0
                                     nullptr, aEvent->IsControl(),
174
0
                                     aEvent->IsAlt(), aEvent->IsShift(),
175
0
                                     aEvent->IsMeta(), aEvent->inputSource);
176
0
}