Lines 1-5
Link Here
|
1 |
/* |
1 |
/* |
2 |
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. |
2 |
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. |
|
|
3 |
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
3 |
* |
4 |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
5 |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions |
6 |
* modification, are permitted provided that the following conditions |
Lines 114-119
using namespace HTMLNames;
Link Here
|
114 |
|
115 |
|
115 |
NSEvent* FrameMac::_currentEvent = nil; |
116 |
NSEvent* FrameMac::_currentEvent = nil; |
116 |
|
117 |
|
|
|
118 |
struct FrameMacDragInfo { |
119 |
RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture |
120 |
bool m_dragSrcIsLink; |
121 |
bool m_dragSrcIsImage; |
122 |
bool m_dragSrcInSelection; |
123 |
bool m_dragSrcMayBeDHTML, m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out? |
124 |
bool m_dragSrcIsDHTML; |
125 |
RefPtr<ClipboardMac> m_dragClipboard; // used on only the source side of dragging |
126 |
}; |
127 |
|
128 |
static FrameMacDragInfo* sharedDragInfo; |
129 |
|
117 |
static const unsigned int escChar = 27; |
130 |
static const unsigned int escChar = 27; |
118 |
static SEL selectorForKeyEvent(const PlatformKeyboardEvent* event) |
131 |
static SEL selectorForKeyEvent(const PlatformKeyboardEvent* event) |
119 |
{ |
132 |
{ |
Lines 156-161
FrameMac::FrameMac(Page* page, Element*
Link Here
|
156 |
, _windowScriptObject(0) |
169 |
, _windowScriptObject(0) |
157 |
, _windowScriptNPObject(0) |
170 |
, _windowScriptNPObject(0) |
158 |
{ |
171 |
{ |
|
|
172 |
if (!sharedDragInfo) |
173 |
sharedDragInfo = new FrameMacDragInfo; |
159 |
} |
174 |
} |
160 |
|
175 |
|
161 |
FrameMac::~FrameMac() |
176 |
FrameMac::~FrameMac() |
Lines 250-257
Frame* FrameMac::createFrame(const KURL&
Link Here
|
250 |
|
265 |
|
251 |
void FrameMac::freeClipboard() |
266 |
void FrameMac::freeClipboard() |
252 |
{ |
267 |
{ |
253 |
if (_dragClipboard) |
268 |
if (sharedDragInfo->m_dragClipboard) |
254 |
_dragClipboard->setAccessPolicy(ClipboardNumb); |
269 |
sharedDragInfo->m_dragClipboard->setAccessPolicy(ClipboardNumb); |
255 |
} |
270 |
} |
256 |
|
271 |
|
257 |
// Either get cached regexp or build one that matches any of the labels. |
272 |
// Either get cached regexp or build one that matches any of the labels. |
Lines 1505-1515
bool FrameMac::dragHysteresisExceeded(fl
Link Here
|
1505 |
IntSize delta = dragLocation - m_mouseDownPos; |
1520 |
IntSize delta = dragLocation - m_mouseDownPos; |
1506 |
|
1521 |
|
1507 |
float threshold = GeneralDragHysteresis; |
1522 |
float threshold = GeneralDragHysteresis; |
1508 |
if (_dragSrcIsImage) |
1523 |
if (sharedDragInfo->m_dragSrcIsImage) |
1509 |
threshold = ImageDragHysteresis; |
1524 |
threshold = ImageDragHysteresis; |
1510 |
else if (_dragSrcIsLink) |
1525 |
else if (sharedDragInfo->m_dragSrcIsLink) |
1511 |
threshold = LinkDragHysteresis; |
1526 |
threshold = LinkDragHysteresis; |
1512 |
else if (_dragSrcInSelection) |
1527 |
else if (sharedDragInfo->m_dragSrcInSelection) |
1513 |
threshold = TextDragHysteresis; |
1528 |
threshold = TextDragHysteresis; |
1514 |
|
1529 |
|
1515 |
return fabsf(delta.width()) >= threshold || fabsf(delta.height()) >= threshold; |
1530 |
return fabsf(delta.width()) >= threshold || fabsf(delta.height()) >= threshold; |
Lines 1520-1570
void FrameMac::handleMouseMoveEvent(cons
Link Here
|
1520 |
BEGIN_BLOCK_OBJC_EXCEPTIONS; |
1535 |
BEGIN_BLOCK_OBJC_EXCEPTIONS; |
1521 |
|
1536 |
|
1522 |
if ([_currentEvent type] == NSLeftMouseDragged) { |
1537 |
if ([_currentEvent type] == NSLeftMouseDragged) { |
1523 |
NSView *view = mouseDownViewIfStillGood(); |
1538 |
if (mouseDownViewIfStillGood()) |
1524 |
|
1539 |
return; // The event has been already dispatched to a subframe |
1525 |
if (view) { |
|
|
1526 |
_sendingEventToSubview = true; |
1527 |
[view mouseDragged:_currentEvent]; |
1528 |
_sendingEventToSubview = false; |
1529 |
return; |
1530 |
} |
1531 |
|
1540 |
|
1532 |
// Careful that the drag starting logic stays in sync with eventMayStartDrag() |
1541 |
// Careful that the drag starting logic stays in sync with eventMayStartDrag() |
1533 |
|
1542 |
|
1534 |
if (mouseDownMayStartDrag() && !_dragSrc) { |
1543 |
if (mouseDownMayStartDrag() && !sharedDragInfo->m_dragSrc) { |
1535 |
BOOL tempFlag1, tempFlag2; |
1544 |
BOOL tempFlag1, tempFlag2; |
1536 |
[_bridge allowDHTMLDrag:&tempFlag1 UADrag:&tempFlag2]; |
1545 |
[_bridge allowDHTMLDrag:&tempFlag1 UADrag:&tempFlag2]; |
1537 |
_dragSrcMayBeDHTML = tempFlag1; |
1546 |
sharedDragInfo->m_dragSrcMayBeDHTML = tempFlag1; |
1538 |
_dragSrcMayBeUA = tempFlag2; |
1547 |
sharedDragInfo->m_dragSrcMayBeUA = tempFlag2; |
1539 |
if (!_dragSrcMayBeDHTML && !_dragSrcMayBeUA) { |
1548 |
if (!sharedDragInfo->m_dragSrcMayBeDHTML && !sharedDragInfo->m_dragSrcMayBeUA) |
1540 |
setMouseDownMayStartDrag(false); // no element is draggable |
1549 |
setMouseDownMayStartDrag(false); // no element is draggable |
1541 |
} |
|
|
1542 |
} |
1550 |
} |
1543 |
|
1551 |
|
1544 |
if (mouseDownMayStartDrag() && !_dragSrc) { |
1552 |
if (mouseDownMayStartDrag() && !sharedDragInfo->m_dragSrc) { |
1545 |
// try to find an element that wants to be dragged |
1553 |
// try to find an element that wants to be dragged |
1546 |
HitTestRequest request(true, false); |
1554 |
HitTestRequest request(true, false); |
1547 |
HitTestResult result(m_mouseDownPos); |
1555 |
HitTestResult result(m_mouseDownPos); |
1548 |
renderer()->layer()->hitTest(request, result); |
1556 |
renderer()->layer()->hitTest(request, result); |
1549 |
Node *node = result.innerNode(); |
1557 |
Node *node = result.innerNode(); |
1550 |
_dragSrc = (node && node->renderer()) ? node->renderer()->draggableNode(_dragSrcMayBeDHTML, _dragSrcMayBeUA, m_mouseDownPos.x(), m_mouseDownPos.y(), _dragSrcIsDHTML) : 0; |
1558 |
sharedDragInfo->m_dragSrc = (node && node->renderer()) ? node->renderer()->draggableNode(sharedDragInfo->m_dragSrcMayBeDHTML, sharedDragInfo->m_dragSrcMayBeUA, m_mouseDownPos.x(), m_mouseDownPos.y(), sharedDragInfo->m_dragSrcIsDHTML) : 0; |
1551 |
if (!_dragSrc) { |
1559 |
if (!sharedDragInfo->m_dragSrc) { |
1552 |
setMouseDownMayStartDrag(false); // no element is draggable |
1560 |
setMouseDownMayStartDrag(false); // no element is draggable |
1553 |
} else { |
1561 |
} else { |
1554 |
// remember some facts about this source, while we have a HitTestResult handy |
1562 |
// remember some facts about this source, while we have a HitTestResult handy |
1555 |
node = result.URLElement(); |
1563 |
node = result.URLElement(); |
1556 |
_dragSrcIsLink = node && node->isLink(); |
1564 |
sharedDragInfo->m_dragSrcIsLink = node && node->isLink(); |
1557 |
|
1565 |
|
1558 |
node = result.innerNonSharedNode(); |
1566 |
node = result.innerNonSharedNode(); |
1559 |
_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage(); |
1567 |
sharedDragInfo->m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage(); |
1560 |
|
1568 |
|
1561 |
_dragSrcInSelection = selectionController()->contains(m_mouseDownPos); |
1569 |
sharedDragInfo->m_dragSrcInSelection = selectionController()->contains(m_mouseDownPos); |
1562 |
} |
1570 |
} |
1563 |
} |
1571 |
} |
1564 |
|
1572 |
|
1565 |
// For drags starting in the selection, the user must wait between the mousedown and mousedrag, |
1573 |
// For drags starting in the selection, the user must wait between the mousedown and mousedrag, |
1566 |
// or else we bail on the dragging stuff and allow selection to occur |
1574 |
// or else we bail on the dragging stuff and allow selection to occur |
1567 |
if (mouseDownMayStartDrag() && _dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) { |
1575 |
if (mouseDownMayStartDrag() && sharedDragInfo->m_dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) { |
1568 |
setMouseDownMayStartDrag(false); |
1576 |
setMouseDownMayStartDrag(false); |
1569 |
// ...but if this was the first click in the window, we don't even want to start selection |
1577 |
// ...but if this was the first click in the window, we don't even want to start selection |
1570 |
if (_activationEventNumber == [_currentEvent eventNumber]) { |
1578 |
if (_activationEventNumber == [_currentEvent eventNumber]) { |
Lines 1586-1592
void FrameMac::handleMouseMoveEvent(cons
Link Here
|
1586 |
NSPoint dragLoc = NSZeroPoint; |
1594 |
NSPoint dragLoc = NSZeroPoint; |
1587 |
NSDragOperation srcOp = NSDragOperationNone; |
1595 |
NSDragOperation srcOp = NSDragOperationNone; |
1588 |
BOOL wcWrotePasteboard = NO; |
1596 |
BOOL wcWrotePasteboard = NO; |
1589 |
if (_dragSrcMayBeDHTML) { |
1597 |
if (sharedDragInfo->m_dragSrcMayBeDHTML) { |
1590 |
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; |
1598 |
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; |
1591 |
// Must be done before ondragstart adds types and data to the pboard, |
1599 |
// Must be done before ondragstart adds types and data to the pboard, |
1592 |
// also done for security, as it erases data from the last drag |
1600 |
// also done for security, as it erases data from the last drag |
Lines 1594-1636
void FrameMac::handleMouseMoveEvent(cons
Link Here
|
1594 |
|
1602 |
|
1595 |
freeClipboard(); // would only happen if we missed a dragEnd. Do it anyway, just |
1603 |
freeClipboard(); // would only happen if we missed a dragEnd. Do it anyway, just |
1596 |
// to make sure it gets numbified |
1604 |
// to make sure it gets numbified |
1597 |
_dragClipboard = new ClipboardMac(true, pasteboard, ClipboardWritable, this); |
1605 |
sharedDragInfo->m_dragClipboard = new ClipboardMac(true, pasteboard, ClipboardWritable, this); |
1598 |
|
1606 |
|
1599 |
// If this is drag of an element, get set up to generate a default image. Otherwise |
1607 |
// If this is drag of an element, get set up to generate a default image. Otherwise |
1600 |
// WebKit will generate the default, the element doesn't override. |
1608 |
// WebKit will generate the default, the element doesn't override. |
1601 |
if (_dragSrcIsDHTML) { |
1609 |
if (sharedDragInfo->m_dragSrcIsDHTML) { |
1602 |
int srcX, srcY; |
1610 |
int srcX, srcY; |
1603 |
_dragSrc->renderer()->absolutePosition(srcX, srcY); |
1611 |
sharedDragInfo->m_dragSrc->renderer()->absolutePosition(srcX, srcY); |
1604 |
IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY); |
1612 |
IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY); |
1605 |
_dragClipboard->setDragImageElement(_dragSrc.get(), IntPoint() + delta); |
1613 |
sharedDragInfo->m_dragClipboard->setDragImageElement(sharedDragInfo->m_dragSrc.get(), IntPoint() + delta); |
1606 |
} |
1614 |
} |
1607 |
|
1615 |
|
1608 |
setMouseDownMayStartDrag(dispatchDragSrcEvent(dragstartEvent, m_mouseDown) && !selectionController()->isInPasswordField()); |
1616 |
setMouseDownMayStartDrag(dispatchDragSrcEvent(dragstartEvent, m_mouseDown) && !selectionController()->isInPasswordField()); |
1609 |
// Invalidate clipboard here against anymore pasteboard writing for security. The drag |
1617 |
// Invalidate clipboard here against anymore pasteboard writing for security. The drag |
1610 |
// image can still be changed as we drag, but not the pasteboard data. |
1618 |
// image can still be changed as we drag, but not the pasteboard data. |
1611 |
_dragClipboard->setAccessPolicy(ClipboardImageWritable); |
1619 |
sharedDragInfo->m_dragClipboard->setAccessPolicy(ClipboardImageWritable); |
1612 |
|
1620 |
|
1613 |
if (mouseDownMayStartDrag()) { |
1621 |
if (mouseDownMayStartDrag()) { |
1614 |
// gather values from DHTML element, if it set any |
1622 |
// gather values from DHTML element, if it set any |
1615 |
_dragClipboard->sourceOperation(srcOp); |
1623 |
sharedDragInfo->m_dragClipboard->sourceOperation(srcOp); |
1616 |
|
1624 |
|
1617 |
NSArray *types = [pasteboard types]; |
1625 |
NSArray *types = [pasteboard types]; |
1618 |
wcWrotePasteboard = types && [types count] > 0; |
1626 |
wcWrotePasteboard = types && [types count] > 0; |
1619 |
|
1627 |
|
1620 |
if (_dragSrcMayBeDHTML) |
1628 |
if (sharedDragInfo->m_dragSrcMayBeDHTML) |
1621 |
dragImage = _dragClipboard->dragNSImage(dragLoc); |
1629 |
dragImage = sharedDragInfo->m_dragClipboard->dragNSImage(dragLoc); |
1622 |
|
1630 |
|
1623 |
// Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with |
1631 |
// Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with |
1624 |
// dragImage! Because of that dumb reentrancy, we may think we've not started the |
1632 |
// dragImage! Because of that dumb reentrancy, we may think we've not started the |
1625 |
// drag when that happens. So we have to assume it's started before we kick it off. |
1633 |
// drag when that happens. So we have to assume it's started before we kick it off. |
1626 |
_dragClipboard->setDragHasStarted(); |
1634 |
sharedDragInfo->m_dragClipboard->setDragHasStarted(); |
1627 |
} |
1635 |
} |
1628 |
} |
1636 |
} |
1629 |
|
1637 |
|
1630 |
if (mouseDownMayStartDrag()) { |
1638 |
if (mouseDownMayStartDrag()) { |
1631 |
BOOL startedDrag = [_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent sourceIsDHTML:_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard]; |
1639 |
BOOL startedDrag = [_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent sourceIsDHTML:sharedDragInfo->m_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard]; |
1632 |
if (!startedDrag && _dragSrcMayBeDHTML) { |
1640 |
if (!startedDrag && sharedDragInfo->m_dragSrcMayBeDHTML) { |
1633 |
// WebKit canned the drag at the last minute - we owe _dragSrc a DRAGEND event |
1641 |
// WebKit canned the drag at the last minute - we owe m_dragSrc a DRAGEND event |
1634 |
PlatformMouseEvent event(PlatformMouseEvent::currentEvent); |
1642 |
PlatformMouseEvent event(PlatformMouseEvent::currentEvent); |
1635 |
dispatchDragSrcEvent(dragendEvent, event); |
1643 |
dispatchDragSrcEvent(dragendEvent, event); |
1636 |
setMouseDownMayStartDrag(false); |
1644 |
setMouseDownMayStartDrag(false); |
Lines 1640-1646
void FrameMac::handleMouseMoveEvent(cons
Link Here
|
1640 |
if (!mouseDownMayStartDrag()) { |
1648 |
if (!mouseDownMayStartDrag()) { |
1641 |
// something failed to start the drag, cleanup |
1649 |
// something failed to start the drag, cleanup |
1642 |
freeClipboard(); |
1650 |
freeClipboard(); |
1643 |
_dragSrc = 0; |
1651 |
sharedDragInfo->m_dragSrc = 0; |
1644 |
} |
1652 |
} |
1645 |
} |
1653 |
} |
1646 |
|
1654 |
|
Lines 1751-1762
void FrameMac::handleMouseReleaseEvent(c
Link Here
|
1751 |
return; |
1759 |
return; |
1752 |
} |
1760 |
} |
1753 |
stopAutoscrollTimer(); |
1761 |
stopAutoscrollTimer(); |
1754 |
|
|
|
1755 |
_sendingEventToSubview = true; |
1756 |
BEGIN_BLOCK_OBJC_EXCEPTIONS; |
1757 |
[view mouseUp:_currentEvent]; |
1758 |
END_BLOCK_OBJC_EXCEPTIONS; |
1759 |
_sendingEventToSubview = false; |
1760 |
} |
1762 |
} |
1761 |
|
1763 |
|
1762 |
bool FrameMac::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe) |
1764 |
bool FrameMac::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe) |
Lines 1849-1855
void FrameMac::mouseDown(NSEvent *event)
Link Here
|
1849 |
prepareForUserAction(); |
1851 |
prepareForUserAction(); |
1850 |
|
1852 |
|
1851 |
_mouseDownView = nil; |
1853 |
_mouseDownView = nil; |
1852 |
_dragSrc = 0; |
1854 |
sharedDragInfo->m_dragSrc = 0; |
1853 |
|
1855 |
|
1854 |
NSEvent *oldCurrentEvent = _currentEvent; |
1856 |
NSEvent *oldCurrentEvent = _currentEvent; |
1855 |
_currentEvent = HardRetain(event); |
1857 |
_currentEvent = HardRetain(event); |
Lines 2954-2979
bool FrameMac::shouldClose()
Link Here
|
2954 |
|
2956 |
|
2955 |
void FrameMac::dragSourceMovedTo(const PlatformMouseEvent& event) |
2957 |
void FrameMac::dragSourceMovedTo(const PlatformMouseEvent& event) |
2956 |
{ |
2958 |
{ |
2957 |
if (_dragSrc && _dragSrcMayBeDHTML) |
2959 |
if (sharedDragInfo->m_dragSrc && sharedDragInfo->m_dragSrcMayBeDHTML) |
2958 |
// for now we don't care if event handler cancels default behavior, since there is none |
2960 |
// for now we don't care if event handler cancels default behavior, since there is none |
2959 |
dispatchDragSrcEvent(dragEvent, event); |
2961 |
dispatchDragSrcEvent(dragEvent, event); |
2960 |
} |
2962 |
} |
2961 |
|
2963 |
|
2962 |
void FrameMac::dragSourceEndedAt(const PlatformMouseEvent& event, NSDragOperation operation) |
2964 |
void FrameMac::dragSourceEndedAt(const PlatformMouseEvent& event, NSDragOperation operation) |
2963 |
{ |
2965 |
{ |
2964 |
if (_dragSrc && _dragSrcMayBeDHTML) { |
2966 |
if (sharedDragInfo->m_dragSrc && sharedDragInfo->m_dragSrcMayBeDHTML) { |
2965 |
_dragClipboard->setDestinationOperation(operation); |
2967 |
sharedDragInfo->m_dragClipboard->setDestinationOperation(operation); |
2966 |
// for now we don't care if event handler cancels default behavior, since there is none |
2968 |
// for now we don't care if event handler cancels default behavior, since there is none |
2967 |
dispatchDragSrcEvent(dragendEvent, event); |
2969 |
dispatchDragSrcEvent(dragendEvent, event); |
2968 |
} |
2970 |
} |
2969 |
freeClipboard(); |
2971 |
freeClipboard(); |
2970 |
_dragSrc = 0; |
2972 |
sharedDragInfo->m_dragSrc = 0; |
2971 |
} |
2973 |
} |
2972 |
|
2974 |
|
2973 |
// returns if we should continue "default processing", i.e., whether eventhandler canceled |
2975 |
// returns if we should continue "default processing", i.e., whether eventhandler canceled |
2974 |
bool FrameMac::dispatchDragSrcEvent(const AtomicString &eventType, const PlatformMouseEvent& event) const |
2976 |
bool FrameMac::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event) const |
2975 |
{ |
2977 |
{ |
2976 |
bool noDefaultProc = d->m_view->dispatchDragEvent(eventType, _dragSrc.get(), event, _dragClipboard.get()); |
2978 |
bool noDefaultProc = d->m_view->dispatchDragEvent(eventType, sharedDragInfo->m_dragSrc.get(), event, sharedDragInfo->m_dragClipboard.get()); |
2977 |
return !noDefaultProc; |
2979 |
return !noDefaultProc; |
2978 |
} |
2980 |
} |
2979 |
|
2981 |
|