[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: Re: Recent selection regressions/showstoppers
From: Stephan Kulow <coolo () kde ! org>
Date: 2004-08-09 8:48:22
Message-ID: 200408091048.22140.coolo () kde ! org
[Download RAW message or body]
Am Samstag 07 August 2004 22:03 schrieb bj@altern.org:
> On Saturday 07 August 2004 17.35, Germain Garand wrote:
> > I think with all due respect for the nice cleanup attempt of Tobias, that
> > rushing such a huge change to the event handling days before a release
> > candidate was really asking for troubles ;(
> > Is there any good reason why this couldn't be postponed until it can
> > safely undergo full testing? there's not even a ChangeLog entry.
>
> I think it is probably better. My fix doesn't seem to cover all issues, and
> I found at least 2 more regressions:
I reverted the attached patch in HEAD and will backport after some testing
Greetings, Stephan
["events.patch" (text/x-diff)]
? patch
Index: khtmlview.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v
retrieving revision 1.662
diff -u -3 -p -u -r1.662 khtmlview.cpp
--- khtmlview.cpp 9 Aug 2004 08:39:46 -0000 1.662
+++ khtmlview.cpp 9 Aug 2004 08:41:12 -0000
@@ -888,9 +888,8 @@ static inline void forwardPeripheralEven
r->absolutePosition(absx, absy);
QPoint p(x-absx, y-absy);
QMouseEvent fw(me->type(), p, me->button(), me->state());
- QWidget* w = r->widget();
- if(w)
- static_cast<khtml::RenderWidget::EventPropagator*>(w)->sendEvent(&fw);
+ if (r->element())
+ r->element()->dispatchMouseEvent(&fw);
}
void KHTMLView::viewportMouseMoveEvent( QMouseEvent * _mouse )
@@ -1374,11 +1373,8 @@ void KHTMLView::keyPressEvent( QKeyEvent
default:
if (d->scrollTimerId)
d->newScrollTimer(this, 0);
- _ke->ignore();
- return;
}
-
- _ke->accept();
+ QScrollView::keyPressEvent(_ke);
}
#ifndef KHTML_NO_TYPE_AHEAD_FIND
@@ -1507,7 +1503,7 @@ bool KHTMLView::focusNextPrevChild( bool
if (m_part->parentPart() && m_part->parentPart()->view())
return m_part->parentPart()->view()->focusNextPrevChild(next);
- return QWidget::focusNextPrevChild(next);
+ return false;
}
void KHTMLView::doAutoScroll()
@@ -1640,37 +1636,6 @@ bool KHTMLView::eventFilter(QObject *o,
pe->rect().width(), pe->rect().height());
}
break;
- case QEvent::MouseMove:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick: {
- if (w->parentWidget() == view && !::qt_cast<QScrollBar *>(w)) {
- QMouseEvent *me = static_cast<QMouseEvent *>(e);
- QPoint pt = (me->pos() + w->pos());
- QMouseEvent me2(me->type(), pt, me->button(), me->state());
-
- if (e->type() == QEvent::MouseMove)
- viewportMouseMoveEvent(&me2);
- else if(e->type() == QEvent::MouseButtonPress)
- viewportMousePressEvent(&me2);
- else if(e->type() == QEvent::MouseButtonRelease)
- viewportMouseReleaseEvent(&me2);
- else
- viewportMouseDoubleClickEvent(&me2);
- block = true;
- }
- break;
- }
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- if (w->parentWidget() == view && !::qt_cast<QScrollBar *>(w)) {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
- if (e->type() == QEvent::KeyPress)
- keyPressEvent(ke);
- else
- keyReleaseEvent(ke);
- block = true;
- }
default:
break;
}
@@ -2549,7 +2514,7 @@ void KHTMLView::viewportWheelEvent(QWhee
QScrollView::viewportWheelEvent( e );
QMouseEvent *tempEvent = new QMouseEvent( QEvent::MouseMove, QPoint(-1,-1), \
QPoint(-1,-1), Qt::NoButton, e->state() );
- emit viewportMouseMoveEvent ( tempEvent );
+ viewportMouseMoveEvent ( tempEvent );
delete tempEvent;
}
Index: html/html_formimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.cpp,v
retrieving revision 1.381
diff -u -3 -p -u -r1.381 html_formimpl.cpp
--- html/html_formimpl.cpp 9 Aug 2004 08:39:46 -0000 1.381
+++ html/html_formimpl.cpp 9 Aug 2004 08:41:12 -0000
@@ -792,22 +792,12 @@ void HTMLGenericFormElementImpl::setDisa
bool HTMLGenericFormElementImpl::isSelectable() const
{
return m_render && m_render->isWidget() &&
- static_cast<RenderWidget*>(m_render)->widget() &&
- static_cast<RenderWidget*>(m_render)->widget()->focusPolicy() >= \
QWidget::TabFocus; + static_cast<RenderWidget*>(m_render)->widget();
}
-class FocusHandleWidget : public QWidget
-{
-public:
- void focusNextPrev(bool n) {
- focusNextPrevChild(n);
- }
-};
-
void HTMLGenericFormElementImpl::defaultEventHandler(EventImpl *evt)
{
- if (evt->target() == this && renderer() && renderer()->isWidget() &&
- !static_cast<RenderWidget*>(renderer())->widget()->inherits("QScrollView")) \
{ + if (evt->target() == this && renderer() && renderer()->isWidget()) {
switch(evt->id()) {
case EventImpl::MOUSEDOWN_EVENT:
case EventImpl::MOUSEUP_EVENT:
@@ -843,25 +833,13 @@ void HTMLGenericFormElementImpl::default
if (m_active)
{
setActive(false);
- setFocus();
+ getDocument()->setFocusNode(this);
}
else {
setActive(false);
}
}
- if (evt->id() == EventImpl::KHTML_KEYPRESS_EVENT) {
- TextEventImpl * k = static_cast<TextEventImpl *>(evt);
- int key = k->qKeyEvent ? k->qKeyEvent->key() : 0;
- if (m_render && (key == Qt::Key_Tab || key == Qt::Key_BackTab)) {
- QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
- if (widget)
- static_cast<FocusHandleWidget *>(widget)
- ->focusNextPrev(key == Qt::Key_Tab);
- }
- }
-
-
if (view && evt->id() == EventImpl::DOMFOCUSOUT_EVENT && isEditable() && m_render \
&& m_render->isWidget()) {
KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension \
*>(view->part()->browserExtension()); QWidget *widget = \
static_cast<RenderWidget*>(m_render)->widget();
Index: rendering/render_form.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_form.cpp,v
retrieving revision 1.270
diff -u -3 -p -u -r1.270 render_form.cpp
--- rendering/render_form.cpp 9 Aug 2004 08:39:46 -0000 1.270
+++ rendering/render_form.cpp 9 Aug 2004 08:41:12 -0000
@@ -114,11 +114,35 @@ short RenderButton::baselinePosition( bo
// -------------------------------------------------------------------------------
+CheckBoxWidget::CheckBoxWidget(QWidget *parent)
+ : QCheckBox(parent, "__khtml")
+{
+}
+
+bool CheckBoxWidget::event(QEvent *e)
+{
+ bool retval = QCheckBox::event(e);
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
+}
+
+// -------------------------------------------------------------------------------
+
RenderCheckBox::RenderCheckBox(HTMLInputElementImpl *element)
: RenderButton(element)
{
- QCheckBox* b = new QCheckBox(view()->viewport(), "__khtml");
+ QCheckBox* b = new CheckBoxWidget(view()->viewport());
b->setAutoMask(true);
b->setMouseTracking(true);
setQWidget(b);
@@ -153,10 +177,34 @@ void RenderCheckBox::slotStateChanged(in
// -------------------------------------------------------------------------------
+RadioButtonWidget::RadioButtonWidget(QWidget *parent)
+ : QRadioButton(parent, "__khtml")
+{
+}
+
+bool RadioButtonWidget::event(QEvent *e)
+{
+ bool retval = QRadioButton::event(e);
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
+}
+
+// -------------------------------------------------------------------------------
+
RenderRadioButton::RenderRadioButton(HTMLInputElementImpl *element)
: RenderButton(element)
{
- QRadioButton* b = new QRadioButton(view()->viewport(), "__khtml");
+ QRadioButton* b = new RadioButtonWidget(view()->viewport());
b->setMouseTracking(true);
setQWidget(b);
}
@@ -183,11 +231,35 @@ void RenderRadioButton::calcMinMaxWidth(
// -------------------------------------------------------------------------------
+FormButtonWidget::FormButtonWidget(QWidget *parent)
+ : QPushButton(parent, "__khtml")
+{
+}
+
+bool FormButtonWidget::event(QEvent *e)
+{
+ bool retval = QPushButton::event(e);
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
+}
+
+// -------------------------------------------------------------------------------
+
RenderSubmitButton::RenderSubmitButton(HTMLInputElementImpl *element)
: RenderButton(element)
{
- QPushButton* p = new QPushButton(view()->viewport(), "__khtml");
+ QPushButton* p = new FormButtonWidget(view()->viewport());
setQWidget(p);
p->setAutoMask(true);
p->setMouseTracking(true);
@@ -391,9 +463,6 @@ void LineEditWidget::extendedMenuActivat
bool LineEditWidget::event( QEvent *e )
{
- if (KLineEdit::event(e))
- return true;
-
if ( e->type() == QEvent::AccelAvailable && isReadOnly() ) {
QKeyEvent* ke = (QKeyEvent*) e;
if ( ke->state() & ControlButton ) {
@@ -410,7 +479,21 @@ bool LineEditWidget::event( QEvent *e )
}
}
}
- return false;
+
+ bool retval = KLineEdit::event(e);
+
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
}
void LineEditWidget::mouseMoveEvent(QMouseEvent *e)
@@ -704,10 +787,34 @@ void RenderFieldset::setStyle(RenderStyl
// -------------------------------------------------------------------------
+FileButtonWidget::FileButtonWidget(QWidget *w, const char *name)
+ : KURLRequester(w, name)
+{
+}
+
+bool FileButtonWidget::event(QEvent *e)
+{
+ bool retval = KURLRequester::event(e);
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
+}
+
+// -------------------------------------------------------------------------
+
RenderFileButton::RenderFileButton(HTMLInputElementImpl *element)
: RenderFormElement(element)
{
- KURLRequester* w = new KURLRequester( view()->viewport(), "__khtml" );
+ KURLRequester* w = new FileButtonWidget( view()->viewport(), "__khtml" );
connect(w->lineEdit(), SIGNAL(returnPressed()), this, \
SLOT(slotReturnPressed()));
connect(w->lineEdit(), SIGNAL(textChanged(const QString \
&)),this,SLOT(slotTextChanged(const QString &))); @@ -808,8 +915,11 @@ \
ComboBoxWidget::ComboBoxWidget(QWidget *
bool ComboBoxWidget::event(QEvent *e)
{
- if (KComboBox::event(e))
+ bool retval = KComboBox::event(e);
+
+ if (retval)
return true;
+
if (e->type()==QEvent::KeyPress)
{
QKeyEvent *ke = static_cast<QKeyEvent *>(e);
@@ -821,10 +931,22 @@ bool ComboBoxWidget::event(QEvent *e)
ke->accept();
return true;
default:
- return false;
+ break;
}
}
- return false;
+
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
}
bool ComboBoxWidget::eventFilter(QObject *dest, QEvent *e)
@@ -854,6 +976,32 @@ bool ComboBoxWidget::eventFilter(QObject
// -------------------------------------------------------------------------
+ListBoxWidget::ListBoxWidget(QWidget *parent, bool multiple)
+ : KListBox(parent, "blah")
+{
+ setMouseTracking(true);
+ setSelectionMode(multiple ? QListBox::Extended : QListBox::Single);
+}
+
+bool ListBoxWidget::event(QEvent *e)
+{
+ bool retval = KListBox::event(e);
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
+ }
+}
+
+// -------------------------------------------------------------------------
+
RenderSelect::RenderSelect(HTMLSelectElementImpl *element)
: RenderFormElement(element)
{
@@ -1143,14 +1291,11 @@ void RenderSelect::setOptionsChanged(boo
KListBox* RenderSelect::createListBox()
{
- KListBox *lb = new KListBox(view()->viewport());
- lb->setSelectionMode(m_multiple ? QListBox::Extended : QListBox::Single);
- // ### looks broken
- //lb->setAutoMask(true);
+ KListBox *lb = new ListBoxWidget(view()->viewport(), m_multiple);
connect( lb, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) \
);
-// connect( lb, SIGNAL( clicked( QListBoxItem * ) ), this, SLOT( slotClicked() ) \
); +
+ // ### is this necessary and wanted?
m_ignoreSelectEvents = false;
- lb->setMouseTracking(true);
return lb;
}
@@ -1511,22 +1656,36 @@ void TextAreaWidget::slotReplace()
bool TextAreaWidget::event( QEvent *e )
{
if ( e->type() == QEvent::AccelAvailable && isReadOnly() ) {
- QKeyEvent* ke = (QKeyEvent*) e;
- if ( ke->state() & ControlButton ) {
- switch ( ke->key() ) {
- case Key_Left:
- case Key_Right:
- case Key_Up:
- case Key_Down:
- case Key_Home:
- case Key_End:
- ke->accept();
- default:
- break;
- }
- }
+ QKeyEvent* ke = (QKeyEvent*) e;
+ if ( ke->state() & ControlButton ) {
+ switch ( ke->key() ) {
+ case Key_Left:
+ case Key_Right:
+ case Key_Up:
+ case Key_Down:
+ case Key_Home:
+ case Key_End:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+
+ bool retval = KTextEdit::event( e );
+
+ switch(e->type())
+ {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return retval;
}
- return KTextEdit::event( e );
}
// -------------------------------------------------------------------------
Index: rendering/render_form.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_form.h,v
retrieving revision 1.114
diff -u -3 -p -u -r1.114 render_form.h
--- rendering/render_form.h 9 Aug 2004 08:39:46 -0000 1.114
+++ rendering/render_form.h 9 Aug 2004 08:41:12 -0000
@@ -127,6 +127,16 @@ protected:
// -------------------------------------------------------------------------
+class CheckBoxWidget : public QCheckBox
+{
+public:
+ CheckBoxWidget(QWidget *parent);
+protected:
+ virtual bool event(QEvent *e);
+};
+
+// -------------------------------------------------------------------------
+
class RenderCheckBox : public RenderButton
{
Q_OBJECT
@@ -147,6 +157,16 @@ public slots:
// -------------------------------------------------------------------------
+class RadioButtonWidget : public QRadioButton
+{
+public:
+ RadioButtonWidget(QWidget *parent);
+protected:
+ virtual bool event(QEvent *e);
+};
+
+// -------------------------------------------------------------------------
+
class RenderRadioButton : public RenderButton
{
public:
@@ -164,6 +184,16 @@ public:
// -------------------------------------------------------------------------
+class FormButtonWidget : public QPushButton
+{
+public:
+ FormButtonWidget(QWidget *parent);
+protected:
+ virtual bool event(QEvent *e);
+};
+
+// -------------------------------------------------------------------------
+
class RenderSubmitButton : public RenderButton
{
public:
@@ -300,6 +330,16 @@ protected:
// -------------------------------------------------------------------------
+class FileButtonWidget : public KURLRequester
+{
+public:
+ FileButtonWidget(QWidget *parent, const char *name);
+ protected:
+ virtual bool event(QEvent *);
+};
+
+// -------------------------------------------------------------------------
+
class RenderFileButton : public RenderFormElement
{
Q_OBJECT
@@ -363,6 +403,16 @@ protected:
virtual bool eventFilter(QObject *dest, QEvent *e);
};
+class ListBoxWidget : public KListBox
+{
+public:
+ ListBoxWidget(QWidget *parent, bool multiple);
+
+protected:
+ virtual bool event(QEvent *);
+};
+
+
// -------------------------------------------------------------------------
class RenderSelect : public RenderFormElement
Index: rendering/render_frames.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_frames.cpp,v
retrieving revision 1.185
diff -u -3 -p -u -r1.185 render_frames.cpp
--- rendering/render_frames.cpp 9 Aug 2004 08:39:46 -0000 1.185
+++ rendering/render_frames.cpp 9 Aug 2004 08:41:12 -0000
@@ -530,6 +530,14 @@ void RenderPart::setWidget( QWidget *wid
slotViewCleared();
}
+bool RenderPart::eventFilter(QObject *o, QEvent *e)
+{
+ if (element() && element()->id() == ID_FRAME && e->type()==QEvent::FocusIn) {
+ element()->getDocument()->setFocusNode(element());
+ }
+ return RenderWidget::eventFilter(o, e);
+}
+
bool RenderPart::partLoadingErrorNotify(khtml::ChildFrame *, const KURL& , const \
QString& ) {
return false;
Index: rendering/render_frames.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_frames.h,v
retrieving revision 1.58
diff -u -3 -p -u -r1.58 render_frames.h
--- rendering/render_frames.h 9 Aug 2004 08:39:46 -0000 1.58
+++ rendering/render_frames.h 9 Aug 2004 08:41:12 -0000
@@ -102,6 +102,8 @@ public:
virtual void setWidget( QWidget *widget );
+ virtual bool eventFilter(QObject *o, QEvent *e);
+
/**
* Called by KHTMLPart to notify the frame object that loading the
* part was not successfuly. (called either asyncroniously after a
Index: rendering/render_replaced.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_replaced.cpp,v
retrieving revision 1.172
diff -u -3 -p -u -r1.172 render_replaced.cpp
--- rendering/render_replaced.cpp 9 Aug 2004 08:39:46 -0000 1.172
+++ rendering/render_replaced.cpp 9 Aug 2004 08:41:12 -0000
@@ -33,15 +33,18 @@
#include <qevent.h>
#include <qapplication.h>
#include <qlineedit.h>
-#include <kglobalsettings.h>
#include <qobjectlist.h>
+#include <qscrollview.h>
+#include <kdebug.h>
+#include <kglobalsettings.h>
#include "khtml_ext.h"
#include "khtmlview.h"
#include "xml/dom2_eventsimpl.h"
#include "khtml_part.h"
#include "xml/dom_docimpl.h"
-#include <kdebug.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
bool khtml::allowWidgetPaintEvents = false;
@@ -96,6 +99,8 @@ RenderWidget::RenderWidget(DOM::NodeImpl
m_view = node->getDocument()->view();
m_resizePending = false;
+ m_ignoreEvents = false;
+
// this is no real reference counting, its just there
// to make sure that we're not deleted while we're recursed
// in an eventFilter of the widget
@@ -113,8 +118,18 @@ void RenderWidget::detach()
m_view->removeChild( m_widget );
}
- m_widget->removeEventFilter( this );
+ if (m_widget->inherits("QScrollView"))
+ {
+ m_widget->removeEventFilter(this);
+ static_cast<QScrollView*>(m_widget)->viewport()->removeEventFilter(this);
+ }
+ else if (m_widget->inherits("KURLRequester"))
+ static_cast<KURLRequester*>(m_widget)->lineEdit()->removeEventFilter(this);
+ else
+ m_widget->removeEventFilter(this);
+
m_widget->setMouseTracking( false );
+ m_ignoreEvents = true;
}
deref();
@@ -181,7 +196,17 @@ void RenderWidget::setQWidget(QWidget *w
if (widget != m_widget)
{
if (m_widget) {
- m_widget->removeEventFilter(this);
+
+ if (m_widget->inherits("QScrollView"))
+ {
+ m_widget->removeEventFilter(this);
+ static_cast<QScrollView*>(m_widget)->viewport()->removeEventFilter(this);
+ }
+ else if (m_widget->inherits("KURLRequester"))
+ static_cast<KURLRequester*>(m_widget)->lineEdit()->removeEventFilter(this);
+ else
+ m_widget->removeEventFilter(this);
+
disconnect( m_widget, SIGNAL( destroyed()), this, SLOT( \
slotWidgetDestructed())); delete m_widget;
m_widget = 0;
@@ -189,13 +214,23 @@ void RenderWidget::setQWidget(QWidget *w
m_widget = widget;
if (m_widget) {
connect( m_widget, SIGNAL( destroyed()), this, SLOT( \
slotWidgetDestructed()));
- m_widget->installEventFilter(this);
+
+ if (m_widget->inherits("QScrollView"))
+ {
+ m_widget->installEventFilter(this);
+ static_cast<QScrollView*>(m_widget)->viewport()->installEventFilter(this);
+ }
+ else if (m_widget->inherits("KURLRequester"))
+ static_cast<KURLRequester*>(m_widget)->lineEdit()->installEventFilter(this);
+ else
+ m_widget->installEventFilter(this);
if ( !strcmp(m_widget->name(), "__khtml"))
m_widget->setBackgroundMode( QWidget::NoBackground );
- if (m_widget->focusPolicy() > QWidget::StrongFocus)
- m_widget->setFocusPolicy(QWidget::StrongFocus);
+ m_widget->setFocusPolicy(QWidget::NoFocus);
+ m_widget->setMouseTracking(true);
+
// if we're already layouted, apply the calculated space to the
// widget immediately
if (layouted()) {
@@ -455,13 +490,26 @@ void RenderWidget::paintWidget(PaintInfo
allowWidgetPaintEvents = false;
}
-bool RenderWidget::eventFilter(QObject* /*o*/, QEvent* e)
+/*
+ before an event is received by the widget,
+ we filter it out in RenderWidget::eventFilter() and propagate it through the DOM.
+ When it arrives at the RenderWidget again, handleEvent() converts the DOM event
+ back to a QEvent and sends it to the widget by calling sendEventToWidget().
+ Events dispatched via sendEventToWidget() must not be filtered again,
+ but they have to be sent via QApplication::notify(),
+ so that other existing event filters aren't skipped.
+*/
+
+bool RenderWidget::eventFilter(QObject* o, QEvent* e)
{
// no special event processing if this is a frame (in which case KHTMLView \
handles it all) if ( ::qt_cast<KHTMLView *>( m_widget ) )
return false;
+
if ( !element() ) return true;
+ if ( m_ignoreEvents ) return false;
+
ref();
element()->ref();
@@ -475,22 +523,56 @@ bool RenderWidget::eventFilter(QObject*
if ( QFocusEvent::reason() != QFocusEvent::Popup )
handleFocusOut();
break;
- case QEvent::FocusIn:
- //kdDebug(6000) << "RenderWidget::eventFilter captures FocusIn" << endl;
- element()->getDocument()->setFocusNode(element());
-// if ( isEditable() ) {
-// KHTMLPartBrowserExtension *ext = \
static_cast<KHTMLPartBrowserExtension *>( element()->view->part()->browserExtension() \
);
-// if ( ext ) ext->editableWidgetFocused( m_widget );
-// }
- break;
case QEvent::KeyPress:
case QEvent::KeyRelease:
- // TODO this seems wrong - Qt events are not correctly translated to DOM ones,
- // like in KHTMLView::dispatchKeyEvent()
- if (element()->dispatchKeyEvent(static_cast<QKeyEvent*>(e),false))
- filtered = true;
+ if (element()->getDocument() && element()->getDocument()->view())
+ {
+ qApp->notify(element()->getDocument()->view(), e);
+ if (static_cast<QKeyEvent*>(e)->isAccepted())
+ filtered = true;
+ }
break;
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ if (element()->getDocument() && element()->getDocument()->view())
+ {
+ QWidget *w = ::qt_cast<QWidget*>(o);
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ QPoint pt = me->pos();
+
+ while (w != element()->getDocument()->view()) {
+ if (element()->getDocument()->view()->childX(w) ||
+ element()->getDocument()->view()->childY(w))
+ {
+ pt += QPoint(element()->getDocument()->view()->childX(w), \
element()->getDocument()->view()->childY(w)); + break;
+ }
+ pt += w->pos();
+ w = w->parentWidget();
+ }
+
+ pt = element()->getDocument()->view()->contentsToViewport(pt);
+
+ // kdDebug(6000)<<"mouse event in RenderWidget with coords (" << \
pt.x()<<"/"<<pt.y()<<")\n"; +
+ QMouseEvent me2(me->type(), pt, me->button(), me->state());
+
+ if (e->type() == QEvent::MouseMove)
+ element()->getDocument()->view()->viewportMouseMoveEvent(&me2);
+ else if(e->type() == QEvent::MouseButtonPress)
+ element()->getDocument()->view()->viewportMousePressEvent(&me2);
+ else if(e->type() == QEvent::MouseButtonRelease)
+ element()->getDocument()->view()->viewportMouseReleaseEvent(&me2);
+ else
+ element()->getDocument()->view()->viewportMouseDoubleClickEvent(&me2);
+
+ filtered = true;
+ break;
+ }
+
case QEvent::Wheel:
if (widget()->parentWidget() == view()->viewport()) {
// don't allow the widget to react to wheel event unless its
@@ -518,30 +600,7 @@ bool RenderWidget::eventFilter(QObject*
return filtered;
}
-void RenderWidget::EventPropagator::sendEvent(QEvent *e) {
- switch(e->type()) {
- case QEvent::MouseButtonPress:
- mousePressEvent(static_cast<QMouseEvent *>(e));
- break;
- case QEvent::MouseButtonRelease:
- mouseReleaseEvent(static_cast<QMouseEvent *>(e));
- break;
- case QEvent::MouseButtonDblClick:
- mouseDoubleClickEvent(static_cast<QMouseEvent *>(e));
- break;
- case QEvent::MouseMove:
- mouseMoveEvent(static_cast<QMouseEvent *>(e));
- break;
- case QEvent::KeyPress:
- keyPressEvent(static_cast<QKeyEvent *>(e));
- break;
- case QEvent::KeyRelease:
- keyReleaseEvent(static_cast<QKeyEvent *>(e));
- break;
- default:
- break;
- }
-}
+// called from GenericFormElementImpl::defaultEventHandler:
bool RenderWidget::handleEvent(const DOM::EventImpl& ev)
{
@@ -607,14 +666,14 @@ bool RenderWidget::handleEvent(const DOM
// << " pos=" << p << " type=" << type
// << " button=" << button << " state=" << state << endl;
QMouseEvent e(type, p, button, state);
- static_cast<EventPropagator *>(m_widget)->sendEvent(&e);
+ sendEventToWidget(&e);
+
break;
}
case EventImpl::KEYDOWN_EVENT:
case EventImpl::KEYUP_EVENT: {
QKeyEvent *ke = static_cast<const TextEventImpl &>(ev).qKeyEvent;
- if (ke)
- static_cast<EventPropagator *>(m_widget)->sendEvent(ke);
+ sendEventToWidget(ke);
break;
}
case EventImpl::KHTML_KEYPRESS_EVENT: {
@@ -633,28 +692,41 @@ bool RenderWidget::handleEvent(const DOM
if (ke && ke->isAutoRepeat()) {
QKeyEvent releaseEv( QEvent::KeyRelease, ke->key(), ke->ascii(), \
ke->state(),
ke->text(), ke->isAutoRepeat(), ke->count() );
- static_cast<EventPropagator *>(m_widget)->sendEvent(&releaseEv);
- static_cast<EventPropagator *>(m_widget)->sendEvent(ke);
- }
+ sendEventToWidget(&releaseEv);
+ sendEventToWidget(ke);
+ }
break;
}
case EventImpl::MOUSEOUT_EVENT: {
QEvent moe( QEvent::Leave );
- QApplication::sendEvent(m_widget, &moe);
+ sendEventToWidget(&moe);
break;
}
case EventImpl::MOUSEOVER_EVENT: {
QEvent moe( QEvent::Enter );
- QApplication::sendEvent(m_widget, &moe);
+ sendEventToWidget(&moe);
break;
}
default:
break;
}
+
return true;
}
+void RenderWidget::sendEventToWidget(QEvent *e)
+{
+ m_ignoreEvents = true;
+ if (m_widget->inherits("QScrollView"))
+ qApp->notify(static_cast<QScrollView*>(m_widget)->viewport(), e);
+ else if (m_widget->inherits("KURLRequester"))
+ qApp->notify(static_cast<KURLRequester*>(m_widget)->lineEdit(), e);
+ else
+ qApp->notify(m_widget, e);
+ m_ignoreEvents = false;
+}
+
void RenderWidget::deref()
{
if (_ref) _ref--;
Index: rendering/render_replaced.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_replaced.h,v
retrieving revision 1.77
diff -u -3 -p -u -r1.77 render_replaced.h
--- rendering/render_replaced.h 9 Aug 2004 08:39:47 -0000 1.77
+++ rendering/render_replaced.h 9 Aug 2004 08:41:12 -0000
@@ -123,16 +123,13 @@ protected:
void setQWidget(QWidget *widget);
void resizeWidget( int w, int h );
+ void sendEventToWidget(QEvent *e);
+
QWidget *m_widget;
KHTMLView* m_view;
bool m_resizePending;
-
-public:
- class EventPropagator : public QWidget {
- public:
- void sendEvent(QEvent *e);
- };
+ bool m_ignoreEvents;
};
extern bool allowWidgetPaintEvents;
Index: xml/dom_docimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_docimpl.cpp,v
retrieving revision 1.290
diff -u -3 -p -u -r1.290 dom_docimpl.cpp
--- xml/dom_docimpl.cpp 9 Aug 2004 08:39:47 -0000 1.290
+++ xml/dom_docimpl.cpp 9 Aug 2004 08:41:12 -0000
@@ -2051,21 +2051,27 @@ void DocumentImpl::setFocusNode(NodeImpl
if (m_focusNode != newFocusNode) return;
m_focusNode->setFocus();
if (m_focusNode != newFocusNode) return;
+ }
+
+ updateRendering();
+ }
- // eww, I suck. set the qt focus correctly
- // ### find a better place in the code for this
+ // ### remove this code as soon as the event flow between frames
+ // is completely handled via the DOM event model.
+ // At the moment, this code is required exactly here (not inside the
+ // if (m_focusNode != newFocusNode) clause), because a form element
+ // which the document erroneously considers the focus widget
+ // can receive focus by a mouse click, e.g. if a widget outside
+ // KHTML was focused before.
if (view()) {
- if (!m_focusNode->renderer() || \
!m_focusNode->renderer()->isWidget()) + if (!m_focusNode || !m_focusNode->renderer() \
|| !m_focusNode->renderer()->isWidget()) view()->setFocus();
- else if \
(static_cast<RenderWidget*>(m_focusNode->renderer())->widget()) + else if \
(static_cast<RenderWidget*>(m_focusNode->renderer())->widget() && + \
qApp->focusWidget() != \
static_cast<RenderWidget*>(m_focusNode->renderer())->widget())
\
static_cast<RenderWidget*>(m_focusNode->renderer())->widget()->setFocus(); }
}
- updateRendering();
- }
-}
-
void DocumentImpl::attachNodeIterator(NodeIteratorImpl *ni)
{
m_nodeIterators.append(ni);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic