Commit c6715640 authored by darin's avatar darin

Reviewed by Ken.

	- fixed 3127898 -- Crash going to altavista.com after visiting sony.com

        * khtml/ecma/kjs_window.cpp: (Window::get): Change lots of properties to return "undefined"
	rather than crashing when the view is NULL. I'm not sure that undefined is the perfect thing
	to return in this case, but it's better than crashing the program. We can refine later as needed.

	- fixed 3127157 -- REGRESSION: applet does not become first responder when clicked-on
	- fixed 3127934 -- Crash in KWQKHTMLPart::widgetWillReleaseView scrolling around

        * kwq/KWQKHTMLPart.h: Get rid of widgetWillReleaseView(). Add mouseDownViewIfStillGood().
        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::passWidgetMouseDownEventToWidget): Call makeFirstResponder: in the same way that
	the NSWindow does before delivering a mouseDown: message. This oversight caused the applet problem.
        (findViewInSubviews): Added.
        (KWQKHTMLPart::mouseDownViewIfStillGood): Added. Gets _mouseDownView, but then checks that it's
	still a subview before returning it. A little inefficient, but the only way to do it given that
	there's no general way to find out that an NSView is being removed from your view hierarchy or deallocated.
	This fixes the crash in widgetWillReleaseView.
        (KWQKHTMLPart::khtmlMouseMoveEvent): Use mouseDownViewIfStillGood() instead of _mouseDownView directly.
        (KWQKHTMLPart::khtmlMouseReleaseEvent): Ditto.
        (KWQKHTMLPart::passSubframeEventToSubframe): Ditto.
        * kwq/KWQWidget.mm:
        (QWidget::~QWidget): Remove call to widgetWillReleaseView().
        (QWidget::setView): Ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3061 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 76287b3e
2002-12-15 Darin Adler <darin@apple.com>
Reviewed by Ken.
- fixed 3127898 -- Crash going to altavista.com after visiting sony.com
* khtml/ecma/kjs_window.cpp: (Window::get): Change lots of properties to return "undefined"
rather than crashing when the view is NULL. I'm not sure that undefined is the perfect thing
to return in this case, but it's better than crashing the program. We can refine later as needed.
- fixed 3127157 -- REGRESSION: applet does not become first responder when clicked-on
- fixed 3127934 -- Crash in KWQKHTMLPart::widgetWillReleaseView scrolling around
* kwq/KWQKHTMLPart.h: Get rid of widgetWillReleaseView(). Add mouseDownViewIfStillGood().
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::passWidgetMouseDownEventToWidget): Call makeFirstResponder: in the same way that
the NSWindow does before delivering a mouseDown: message. This oversight caused the applet problem.
(findViewInSubviews): Added.
(KWQKHTMLPart::mouseDownViewIfStillGood): Added. Gets _mouseDownView, but then checks that it's
still a subview before returning it. A little inefficient, but the only way to do it given that
there's no general way to find out that an NSView is being removed from your view hierarchy or deallocated.
This fixes the crash in widgetWillReleaseView.
(KWQKHTMLPart::khtmlMouseMoveEvent): Use mouseDownViewIfStillGood() instead of _mouseDownView directly.
(KWQKHTMLPart::khtmlMouseReleaseEvent): Ditto.
(KWQKHTMLPart::passSubframeEventToSubframe): Ditto.
* kwq/KWQWidget.mm:
(QWidget::~QWidget): Remove call to widgetWillReleaseView().
(QWidget::setView): Ditto.
2002-12-15 David Hyatt <hyatt@apple.com>
operator== on CSSSelectors needed to be updated to compare
......
2002-12-15 Darin Adler <darin@apple.com>
Reviewed by Ken.
- fixed 3127898 -- Crash going to altavista.com after visiting sony.com
* khtml/ecma/kjs_window.cpp: (Window::get): Change lots of properties to return "undefined"
rather than crashing when the view is NULL. I'm not sure that undefined is the perfect thing
to return in this case, but it's better than crashing the program. We can refine later as needed.
- fixed 3127157 -- REGRESSION: applet does not become first responder when clicked-on
- fixed 3127934 -- Crash in KWQKHTMLPart::widgetWillReleaseView scrolling around
* kwq/KWQKHTMLPart.h: Get rid of widgetWillReleaseView(). Add mouseDownViewIfStillGood().
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::passWidgetMouseDownEventToWidget): Call makeFirstResponder: in the same way that
the NSWindow does before delivering a mouseDown: message. This oversight caused the applet problem.
(findViewInSubviews): Added.
(KWQKHTMLPart::mouseDownViewIfStillGood): Added. Gets _mouseDownView, but then checks that it's
still a subview before returning it. A little inefficient, but the only way to do it given that
there's no general way to find out that an NSView is being removed from your view hierarchy or deallocated.
This fixes the crash in widgetWillReleaseView.
(KWQKHTMLPart::khtmlMouseMoveEvent): Use mouseDownViewIfStillGood() instead of _mouseDownView directly.
(KWQKHTMLPart::khtmlMouseReleaseEvent): Ditto.
(KWQKHTMLPart::passSubframeEventToSubframe): Ditto.
* kwq/KWQWidget.mm:
(QWidget::~QWidget): Remove call to widgetWillReleaseView().
(QWidget::setView): Ditto.
2002-12-15 David Hyatt <hyatt@apple.com>
operator== on CSSSelectors needed to be updated to compare
......
......@@ -434,8 +434,12 @@ Value Window::get(ExecState *exec, const Identifier &p) const
return Undefined();
}
case InnerHeight:
if (!m_part->view())
return Undefined();
return Number(m_part->view()->visibleHeight());
case InnerWidth:
if (!m_part->view())
return Undefined();
return Number(m_part->view()->visibleWidth());
case Length:
return Number(m_part->frames().count());
......@@ -470,8 +474,12 @@ Value Window::get(ExecState *exec, const Identifier &p) const
inf.geometry.height() : inf.geometry.width());
}
case PageXOffset:
if (!m_part->view())
return Undefined();
return Number(m_part->view()->contentsX());
case PageYOffset:
if (!m_part->view())
return Undefined();
return Number(m_part->view()->contentsY());
case Parent:
return Value(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part));
......@@ -479,18 +487,26 @@ Value Window::get(ExecState *exec, const Identifier &p) const
return Undefined(); // ###
case ScreenLeft:
case ScreenX: {
QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
if (!m_part->view())
return Undefined();
QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
return Number(m_part->view()->mapToGlobal(QPoint(0,0)).x() + sg.x());
}
case ScreenTop:
case ScreenY: {
QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
if (!m_part->view())
return Undefined();
QRect sg = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(m_part->view()));
return Number(m_part->view()->mapToGlobal(QPoint(0,0)).y() + sg.y());
}
case ScrollX: {
if (!m_part->view())
return Undefined();
return Number(m_part->view()->contentsX());
}
case ScrollY: {
if (!m_part->view())
return Undefined();
return Number(m_part->view()->contentsY());
}
case Scrollbars:
......
......@@ -147,8 +147,6 @@ public:
void mouseMoved(NSEvent *);
bool keyEvent(NSEvent *);
static void widgetWillReleaseView(NSView *);
void clearTimers();
static void clearTimers(KHTMLView *);
......@@ -171,6 +169,8 @@ private:
bool passWidgetMouseDownEventToWidget(khtml::RenderWidget *);
void setPolicyBaseURL(const DOM::DOMString &);
NSView *mouseDownViewIfStillGood();
WebCoreBridge *bridgeForFrameName(const QString &frameName);
......
......@@ -764,7 +764,13 @@ bool KWQKHTMLPart::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget)
ERROR("KHTML says we hit a RenderWidget, but AppKit doesn't agree we hit the corresponding NSView");
return false;
}
// Normally [NSWindow sendEvent:] handles this.
// But in our case, the event was sent to the view representing the entire web page.
if ([view acceptsFirstResponder]) {
[[view window] makeFirstResponder:view];
}
ASSERT(!_sendingEventToSubview);
_sendingEventToSubview = true;
[view mouseDown:_currentEvent];
......@@ -777,42 +783,69 @@ bool KWQKHTMLPart::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget)
return true;
}
// Note that this does the same kind of check as [target isDescendantOf:superview].
// There are two differences: This is a lot slower because it has to walk the whole
// tree, and this works in cases where the target has already been deallocated.
static bool findViewInSubviews(NSView *superview, NSView *target)
{
NSEnumerator *e = [[superview subviews] objectEnumerator];
NSView *subview;
while ((subview = [e nextObject])) {
if (subview == target || findViewInSubviews(subview, target))
return true;
}
return false;
}
NSView *KWQKHTMLPart::mouseDownViewIfStillGood()
{
// Since we have no way of tracking the lifetime of _mouseDownView, we have to assume that
// it could be deallocated already. We search for it in our subview tree; if we don't find
// it, we set it to nil.
NSView *mouseDownView = _mouseDownView;
if (!mouseDownView) {
return nil;
}
KHTMLView *topKHTMLView = d->m_view;
NSView *topView = topKHTMLView ? topKHTMLView->getView() : nil;
if (!topView || !findViewInSubviews(topView, mouseDownView)) {
_mouseDownView = nil;
return nil;
}
return mouseDownView;
}
void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
{
if (!_mouseDownView || [_currentEvent type] != NSLeftMouseDragged) {
NSView *view;
if ([_currentEvent type] != NSLeftMouseDragged) {
view = nil;
} else {
view = mouseDownViewIfStillGood();
}
if (!view) {
KHTMLPart::khtmlMouseMoveEvent(event);
return;
}
_sendingEventToSubview = true;
[_mouseDownView mouseDragged:_currentEvent];
[view mouseDragged:_currentEvent];
_sendingEventToSubview = false;
}
void KWQKHTMLPart::khtmlMouseReleaseEvent(MouseReleaseEvent *event)
{
if (!_mouseDownView) {
NSView *view = mouseDownViewIfStillGood();
if (!view) {
KHTMLPart::khtmlMouseReleaseEvent(event);
return;
}
_sendingEventToSubview = true;
[_mouseDownView mouseUp:_currentEvent];
[view mouseUp:_currentEvent];
_sendingEventToSubview = false;
}
void KWQKHTMLPart::widgetWillReleaseView(NSView *view)
{
if (view == nil) {
return;
}
for (QPtrListIterator<KWQKHTMLPart> it(instances()); it.current(); ++it) {
if ([it.current()->_mouseDownView isDescendantOf:view]) {
it.current()->_mouseDownView = nil;
}
}
}
void KWQKHTMLPart::clearTimers(KHTMLView *view)
{
if (view) {
......@@ -844,24 +877,34 @@ bool KWQKHTMLPart::passSubframeEventToSubframe(DOM::NodeImpl::MouseEvent &event)
_mouseDownWasInSubframe = true;
return true;
}
case NSLeftMouseUp:
if (!(_mouseDownView && _mouseDownWasInSubframe)) {
case NSLeftMouseUp: {
if (!_mouseDownWasInSubframe) {
return false;
}
NSView *view = mouseDownViewIfStillGood();
if (!view) {
return false;
}
ASSERT(!_sendingEventToSubview);
_sendingEventToSubview = true;
[_mouseDownView mouseUp:_currentEvent];
[view mouseUp:_currentEvent];
_sendingEventToSubview = false;
return true;
case NSLeftMouseDragged:
if (!(_mouseDownView && _mouseDownWasInSubframe)) {
}
case NSLeftMouseDragged: {
if (!_mouseDownWasInSubframe) {
return false;
}
NSView *view = mouseDownViewIfStillGood();
if (!view) {
return false;
}
ASSERT(!_sendingEventToSubview);
_sendingEventToSubview = true;
[_mouseDownView mouseDragged:_currentEvent];
[view mouseDragged:_currentEvent];
_sendingEventToSubview = false;
return true;
}
default:
return false;
}
......
......@@ -72,7 +72,6 @@ QWidget::QWidget(NSView *view)
QWidget::~QWidget()
{
KWQKHTMLPart::widgetWillReleaseView(data->view);
[data->view release];
delete data;
}
......@@ -349,7 +348,6 @@ void QWidget::setView(NSView *view)
return;
}
KWQKHTMLPart::widgetWillReleaseView(getOuterView());
[data->view release];
data->view = [view retain];
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment