27
27
#include "EventHandler.h"
29
29
#include "BlockExceptions.h"
30
#include "ChromeClient.h"
30
31
#include "ClipboardMac.h"
33
#include "DragController.h"
34
32
#include "EventNames.h"
35
#include "FloatPoint.h"
36
33
#include "FocusController.h"
37
#include "FoundationExtras.h"
38
34
#include "FrameLoader.h"
40
#include "FrameTree.h"
41
36
#include "FrameView.h"
42
#include "HTMLFrameOwnerElement.h"
43
#include "HTMLFrameSetElement.h"
44
#include "HitTestRequest.h"
45
#include "HitTestResult.h"
46
37
#include "KeyboardEvent.h"
47
38
#include "MouseEventWithHitTestResults.h"
50
41
#include "PlatformScrollBar.h"
51
42
#include "PlatformWheelEvent.h"
52
43
#include "RenderWidget.h"
53
#include "WebCoreFrameBridge.h"
55
46
namespace WebCore {
57
48
using namespace EventNames;
50
unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
52
const double EventHandler::TextDragDelay = 0.15;
59
54
static RetainPtr<NSEvent>& currentEvent()
61
56
static RetainPtr<NSEvent> event;
128
131
return handlingOptionTab;
134
bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
136
static BOOL checkedSafari = NO;
137
static BOOL isSafari = NO;
139
if (!checkedSafari) {
140
isSafari = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"];
144
Document* document = m_frame->document();
148
// RSS view needs arrow key keypress events.
149
if (isSafari && document->url().protocolIs("feed") || document->url().protocolIs("feeds"))
151
Settings* settings = m_frame->settings();
155
#if ENABLE(DASHBOARD_SUPPORT)
156
if (settings->usesDashboardBackwardCompatibilityMode())
160
if (settings->needsKeyboardEventDisambiguationQuirks())
131
166
bool EventHandler::keyEvent(NSEvent *event)
215
251
ASSERT(nodeView);
216
252
ASSERT([nodeView superview]);
217
253
NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
219
255
// We probably hit the border of a RenderWidget
222
if ([m_frame->bridge() firstResponder] == view) {
223
// In the case where we just became first responder, we should send the mouseDown:
224
// to the NSTextField, not the NSTextField's editor. This code makes sure that happens.
225
// If we don't do this, we see a flash of selected text when clicking in a text field.
226
// FIXME: This is the only caller of textViewWasFirstResponderAtMouseDownTime. When we
227
// eliminate all use of NSTextField/NSTextView in form fields we can eliminate this code,
228
// and textViewWasFirstResponderAtMouseDownTime:, and the instance variable WebHTMLView
229
// keeps solely to support textViewWasFirstResponderAtMouseDownTime:.
230
if ([view isKindOfClass:[NSTextView class]] && ![m_frame->bridge() textViewWasFirstResponderAtMouseDownTime:(NSTextView *)view]) {
231
NSView *superview = view;
232
while (superview != nodeView) {
233
superview = [superview superview];
235
if ([superview isKindOfClass:[NSControl class]]) {
236
NSControl *control = static_cast<NSControl*>(superview);
237
if ([control currentEditor] == view)
259
Page* page = m_frame->page();
263
if (page->chrome()->client()->firstResponder() != view) {
244
264
// Normally [NSWindow sendEvent:] handles setting the first responder.
245
265
// But in our case, the event was sent to the view representing the entire web page.
246
if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey]) {
247
[m_frame->bridge() makeFirstResponder:view];
266
if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey])
267
page->chrome()->client()->makeFirstResponder(view);
251
270
// We need to "defer loading" while tracking the mouse, because tearing down the
255
274
// mouse. We should confirm that, and then remove the deferrsLoading
256
275
// hack entirely.
258
bool wasDeferringLoading = m_frame->page()->defersLoading();
277
bool wasDeferringLoading = page->defersLoading();
259
278
if (!wasDeferringLoading)
260
m_frame->page()->setDefersLoading(true);
279
page->setDefersLoading(true);
262
281
ASSERT(!m_sendingEventToSubview);
263
282
m_sendingEventToSubview = true;
346
Clipboard* EventHandler::createDraggingClipboard() const
365
PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
348
367
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
349
368
// Must be done before ondragstart adds types and data to the pboard,
350
369
// also done for security, as it erases data from the last drag
351
370
[pasteboard declareTypes:[NSArray array] owner:nil];
352
return new ClipboardMac(true, pasteboard, ClipboardWritable, m_frame);
371
return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame);
355
374
bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
547
569
NSEvent *fakeEvent = nil;
548
570
if (eventType == NSLeftMouseDown) {
549
571
fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
550
location:[initiatingEvent locationInWindow]
551
modifierFlags:[initiatingEvent modifierFlags]
552
timestamp:[initiatingEvent timestamp]
553
windowNumber:[initiatingEvent windowNumber]
554
context:[initiatingEvent context]
555
eventNumber:[initiatingEvent eventNumber]
556
clickCount:[initiatingEvent clickCount]
557
pressure:[initiatingEvent pressure]];
572
location:[initiatingEvent locationInWindow]
573
modifierFlags:[initiatingEvent modifierFlags]
574
timestamp:[initiatingEvent timestamp]
575
windowNumber:[initiatingEvent windowNumber]
576
context:[initiatingEvent context]
577
eventNumber:[initiatingEvent eventNumber]
578
clickCount:[initiatingEvent clickCount]
579
pressure:[initiatingEvent pressure]];
559
581
[NSApp postEvent:fakeEvent atStart:YES];
560
582
} else { // eventType == NSKeyDown
561
583
fakeEvent = [NSEvent keyEventWithType:NSKeyUp
562
location:[initiatingEvent locationInWindow]
563
modifierFlags:[initiatingEvent modifierFlags]
564
timestamp:[initiatingEvent timestamp]
565
windowNumber:[initiatingEvent windowNumber]
566
context:[initiatingEvent context]
567
characters:[initiatingEvent characters]
568
charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers]
569
isARepeat:[initiatingEvent isARepeat]
570
keyCode:[initiatingEvent keyCode]];
584
location:[initiatingEvent locationInWindow]
585
modifierFlags:[initiatingEvent modifierFlags]
586
timestamp:[initiatingEvent timestamp]
587
windowNumber:[initiatingEvent windowNumber]
588
context:[initiatingEvent context]
589
characters:[initiatingEvent characters]
590
charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers]
591
isARepeat:[initiatingEvent isARepeat]
592
keyCode:[initiatingEvent keyCode]];
571
593
[NSApp postEvent:fakeEvent atStart:YES];
573
// FIXME: We should really get the current modifierFlags here, but there's no way to poll
595
// FIXME: We should really get the current modifierFlags here, but there's no way to poll
574
596
// them in Cocoa, and because the event stream was stolen by the Carbon menu code we have
575
597
// no up-to-date cache of them anywhere.
576
598
fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved
577
location:[[m_frame->bridge() window] convertScreenToBase:[NSEvent mouseLocation]]
599
location:[[view->getView() window] convertScreenToBase:[NSEvent mouseLocation]]
578
600
modifierFlags:[initiatingEvent modifierFlags]
579
601
timestamp:[initiatingEvent timestamp]
580
602
windowNumber:[initiatingEvent windowNumber]