[iOS] Keyups for non-modifier keys identified as "Dead" when not focused in a content...
[WebKit-https.git] / Source / WebCore / platform / ios / WidgetIOS.mm
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "config.h"
27 #import "Widget.h"
28
29 #if PLATFORM(IOS_FAMILY)
30
31 #import "Cursor.h"
32 #import "Document.h"
33 #import "FontCascade.h"
34 #import "Frame.h"
35 #import "GraphicsContext.h"
36 #import "PlatformMouseEvent.h"
37 #import "ScrollView.h"
38 #import "WAKScrollView.h"
39 #import "WAKView.h"
40 #import "WAKWindow.h"
41 #import "WebCoreFrameView.h"
42 #import "WebCoreView.h"
43 #import <wtf/BlockObjCExceptions.h>
44
45 @interface NSView (WebSetSelectedMethods)
46 - (void)setIsSelected:(BOOL)isSelected;
47 - (void)webPlugInSetIsSelected:(BOOL)isSelected;
48 @end
49
50 namespace WebCore {
51
52 static void safeRemoveFromSuperview(NSView *view)
53 {
54     // FIXME: we should probably change the first responder of the window if
55     // it is a descendant of the view we remove.
56     // See: <rdar://problem/10360186>
57     [view removeFromSuperview];
58 }
59
60 Widget::Widget(NSView* view)
61 {
62     init(view);
63 }
64
65 Widget::~Widget() 
66 {
67     releasePlatformWidget();
68 }
69
70 // FIXME: Should move this to Chrome; bad layering that this knows about Frame.
71 void Widget::setFocus(bool focused)
72 {
73     UNUSED_PARAM(focused);
74 }
75
76 void Widget::setCursor(const Cursor&)
77 {
78 }
79
80 void Widget::show()
81 {
82     if (isSelfVisible())
83         return;
84
85     setSelfVisible(true);
86
87     BEGIN_BLOCK_OBJC_EXCEPTIONS;
88     [getOuterView() setHidden:NO];
89     END_BLOCK_OBJC_EXCEPTIONS;
90 }
91
92 void Widget::hide()
93 {
94     if (!isSelfVisible())
95         return;
96
97     setSelfVisible(false);
98
99     BEGIN_BLOCK_OBJC_EXCEPTIONS;
100     [getOuterView() setHidden:YES];
101     END_BLOCK_OBJC_EXCEPTIONS;
102 }
103
104 IntRect Widget::frameRect() const
105 {
106     if (!platformWidget())
107         return m_frame;
108     
109     BEGIN_BLOCK_OBJC_EXCEPTIONS;
110     return enclosingIntRect([getOuterView() frame]);
111     END_BLOCK_OBJC_EXCEPTIONS;
112     
113     return m_frame;
114 }
115
116 void Widget::setFrameRect(const IntRect &rect)
117 {
118     m_frame = rect;
119     
120     BEGIN_BLOCK_OBJC_EXCEPTIONS;
121     NSView *v = getOuterView();
122     NSRect f = rect;
123     if (!NSEqualRects(f, [v frame])) {
124         [v setFrame:f];
125         [v setNeedsDisplay: NO];
126     }
127     END_BLOCK_OBJC_EXCEPTIONS;
128 }
129
130 NSView* Widget::getOuterView() const
131 {
132     NSView* view = platformWidget();
133
134     // If this widget's view is a WebCoreFrameScrollView then we
135     // resize its containing view, a WebFrameView.
136     if ([view conformsToProtocol:@protocol(WebCoreFrameScrollView)]) {
137         view = [view superview];
138         ASSERT(view);
139     }
140
141     return view;
142 }
143
144 void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy)
145 {
146     if (p.paintingDisabled())
147         return;
148     
149     NSView *view = getOuterView();
150
151     CGContextRef cgContext = p.platformContext();
152     CGContextSaveGState(cgContext);
153
154     NSRect viewFrame = [view frame];
155     NSRect viewBounds = [view bounds];
156     CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y - viewBounds.origin.y);
157
158     BEGIN_BLOCK_OBJC_EXCEPTIONS;
159     [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:cgContext];
160     END_BLOCK_OBJC_EXCEPTIONS;
161
162     CGContextRestoreGState(cgContext);
163 }
164
165 void Widget::setIsSelected(bool /*isSelected*/)
166 {
167 }
168
169 void Widget::addToSuperview(NSView *view)
170 {
171     BEGIN_BLOCK_OBJC_EXCEPTIONS;
172
173     ASSERT(view);
174     NSView *subview = getOuterView();
175
176     if (!subview)
177         return;
178
179     ASSERT(![view isDescendantOf:subview]);
180     
181     if ([subview superview] != view)
182         [view addSubview:subview];
183
184     END_BLOCK_OBJC_EXCEPTIONS;
185 }
186
187 void Widget::removeFromSuperview()
188 {
189     BEGIN_BLOCK_OBJC_EXCEPTIONS;
190     safeRemoveFromSuperview(getOuterView());
191     END_BLOCK_OBJC_EXCEPTIONS;
192 }
193
194 IntRect Widget::convertFromRootToContainingWindow(const Widget* rootWidget, const IntRect& rect)
195 {
196     if (!rootWidget->platformWidget())
197         return rect;
198
199     BEGIN_BLOCK_OBJC_EXCEPTIONS;
200     ASSERT([rootWidget->platformWidget() isKindOfClass:[NSScrollView class]]);
201     WAKScrollView *view = static_cast<WAKScrollView *>(rootWidget->platformWidget());
202     if (WAKView *documentView = [view documentView])
203         return enclosingIntRect([documentView convertRect:rect toView:nil]);
204     return enclosingIntRect([view convertRect:rect toView:nil]);
205     END_BLOCK_OBJC_EXCEPTIONS;
206
207     return rect;
208 }
209
210 IntRect Widget::convertFromContainingWindowToRoot(const Widget* rootWidget, const IntRect& rect)
211 {
212     if (!rootWidget->platformWidget())
213         return rect;
214
215     BEGIN_BLOCK_OBJC_EXCEPTIONS;
216     ASSERT([rootWidget->platformWidget() isKindOfClass:[NSScrollView class]]);
217     WAKScrollView *view = static_cast<WAKScrollView *>(rootWidget->platformWidget());
218     if (WAKView *documentView = [view documentView])
219         return enclosingIntRect([documentView convertRect:rect fromView:nil]);
220     return enclosingIntRect([view convertRect:rect fromView:nil]);
221     END_BLOCK_OBJC_EXCEPTIONS;
222
223     return rect;
224 }
225
226 IntPoint Widget::convertFromRootToContainingWindow(const Widget* rootWidget, const IntPoint& point)
227 {
228     if (!rootWidget->platformWidget())
229         return point;
230
231     BEGIN_BLOCK_OBJC_EXCEPTIONS;
232     ASSERT([rootWidget->platformWidget() isKindOfClass:[NSScrollView class]]);
233     WAKScrollView *view = static_cast<WAKScrollView *>(rootWidget->platformWidget());
234     NSPoint convertedPoint;
235     if (WAKView *documentView = [view documentView])
236         convertedPoint = [documentView convertPoint:point toView:nil];
237     else
238         convertedPoint = [view convertPoint:point toView:nil];
239     return IntPoint(roundf(convertedPoint.x), roundf(convertedPoint.y));
240     END_BLOCK_OBJC_EXCEPTIONS;
241
242     return point;
243 }
244
245 IntPoint Widget::convertFromContainingWindowToRoot(const Widget* rootWidget, const IntPoint& point)
246 {
247     if (!rootWidget->platformWidget())
248         return point;
249
250     BEGIN_BLOCK_OBJC_EXCEPTIONS;
251     ASSERT([rootWidget->platformWidget() isKindOfClass:[NSScrollView class]]);
252     WAKScrollView *view = static_cast<WAKScrollView *>(rootWidget->platformWidget());
253     NSPoint convertedPoint;
254     if (WAKView *documentView = [view documentView])
255         convertedPoint = IntPoint([documentView convertPoint:point fromView:nil]);
256     else
257         convertedPoint = IntPoint([view convertPoint:point fromView:nil]);
258     return IntPoint(roundf(convertedPoint.x), roundf(convertedPoint.y));
259     END_BLOCK_OBJC_EXCEPTIONS;
260
261     return point;
262 }
263
264 NSView *Widget::platformWidget() const
265 {
266     return m_widget.get();
267 }
268
269 void Widget::setPlatformWidget(NSView *widget)
270 {
271     if (widget == m_widget)
272         return;
273
274     m_widget = widget;
275 }
276
277 }
278
279 #endif // PLATFORM(IOS_FAMILY)