Fix bugs 4445, 4768. Make form widgets work a little better. This includes:

1) Radio/Toggle button initial state properly set.
2) Radio/Toggle button toggling works as expected.
3) Form Buttons work/submit on the first click as expected.

The problem was that enter/leave events expected by the form controlling
frames were not properly emitted.  They were being emitted for the parent
widget and not the buttons.

I also had to add a pathetically lame hack to work around artificial
intelligence in the GtkToggleButton widget.  Because the gtk toggle widget
changes its state on button press, we are out of whack by one.

Finally, some minor cleanup to event debug code in nsWidget.


git-svn-id: svn://10.0.0.236/trunk@29994 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
ramiro%netscape.com 1999-05-03 21:29:28 +00:00
parent 41f30ca064
commit ce703464bd
6 changed files with 57 additions and 29 deletions

View File

@ -65,6 +65,9 @@ void nsButton::InitCallbacks(char * aName)
InstallButtonPressSignal(mWidget);
InstallButtonReleaseSignal(mWidget);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |

View File

@ -35,6 +35,8 @@ nsCheckButton::nsCheckButton() : nsWidget() , nsICheckButton()
NS_INIT_REFCNT();
mLabel = nsnull;
mCheckButton = nsnull;
mState = PR_FALSE;
mFirstTime = PR_TRUE;
}
//-------------------------------------------------------------------------
@ -84,6 +86,9 @@ void nsCheckButton::InitCallbacks(char * aName)
InstallButtonPressSignal(mCheckButton);
InstallButtonReleaseSignal(mCheckButton);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |
@ -133,13 +138,14 @@ nsresult nsCheckButton::QueryInterface(const nsIID& aIID, void** aInstancePtr)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::SetState(const PRBool aState)
{
if (mWidget) {
GtkToggleButton * item = GTK_TOGGLE_BUTTON(mCheckButton);
mState = aState;
item->active = (gboolean) aState;
gtk_widget_queue_draw(GTK_WIDGET(item));
if (mWidget && mCheckButton)
{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mCheckButton),
(gboolean) mState);
}
return NS_OK;
}
@ -150,14 +156,19 @@ NS_METHOD nsCheckButton::SetState(const PRBool aState)
//-------------------------------------------------------------------------
NS_METHOD nsCheckButton::GetState(PRBool& aState)
{
aState = PR_TRUE;
if (mWidget) {
aState = (PRBool) GTK_TOGGLE_BUTTON(mCheckButton)->active;
aState = mState;
// The check button will have been toggled twice (cough) -
// once by GTK and once by gecko. This is obviously messed up.
aState = !aState;
// Pathetically lame hack to work around artificial intelligence
// in the GtkToggleButton widget. Because the gtk toggle widget
// changes its state on button press, we are out of whack by one
//
if (mFirstTime)
{
mFirstTime = PR_FALSE;
aState = !mState;
}
return NS_OK;
}

View File

@ -57,6 +57,13 @@ protected:
GtkWidget *mLabel;
GtkWidget *mCheckButton;
// We need to maintain our own state to be in sync with the
// gecko check controlling frame.
PRBool mState;
// See GetState()
PRBool mFirstTime;
};
#endif // nsCheckButton_h__

View File

@ -119,6 +119,9 @@ void nsRadioButton::InitCallbacks(char * aName)
InstallButtonPressSignal(mRadioButton);
InstallButtonReleaseSignal(mRadioButton);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
// These are needed so that the events will go to us and not our parent.
AddToEventMask(mWidget,
GDK_BUTTON_PRESS_MASK |

View File

@ -1155,7 +1155,10 @@ nsWidget::InstallRealizeSignal(GtkWidget * aWidget)
#ifdef TRACE_MOUSE_EVENTS
static void
DebugPrintMouseEvent(nsMouseEvent & aEvent,char * sMessage,void * instance)
DebugPrintMouseEvent(nsMouseEvent & aEvent,
char * sMessage,
nsWidget * aInstance,
GtkWidget * aGtkWidget)
{
char * eventName = nsnull;
@ -1227,14 +1230,14 @@ DebugPrintMouseEvent(nsMouseEvent & aEvent,char * sMessage,void * instance)
static int sPrintCount=0;
printf("%4d %s(this=%p,%s,x=%d,y=%d,click=%d)\n",
printf("%4d %s(this=%p,name=%s,event=%s,x=%d,y=%d)\n",
sPrintCount++,
sMessage,
instance,
aInstance,
gtk_widget_get_name(aGtkWidget),
eventName,
aEvent.point.x,
aEvent.point.y,
aEvent.clickCount);
aEvent.point.y);
}
#endif // TRACE_MOUSE_EVENTS
//////////////////////////////////////////////////////////////////
@ -1262,7 +1265,7 @@ nsWidget::OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent)
// the GtkWidget corresponding to the sButtonMotionTarget and
// marking if nsnull in there.
//
if (sButtonMotionTarget != nsnull)
if (nsnull != sButtonMotionTarget)
{
gint diffX;
gint diffY;
@ -1298,7 +1301,7 @@ nsWidget::OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent)
}
#ifdef TRACE_MOUSE_EVENTS
DebugPrintMouseEvent(event,"Motion",this);
DebugPrintMouseEvent(event,"Motion",this,mWidget);
#endif
AddRef();
@ -1318,7 +1321,7 @@ nsWidget::OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent)
//
// XXX ramiro - Same as above.
//
if (sButtonMotionTarget != nsnull)
if (nsnull != sButtonMotionTarget)
{
return;
}
@ -1337,7 +1340,7 @@ nsWidget::OnEnterNotifySignal(GdkEventCrossing * aGdkCrossingEvent)
}
#ifdef TRACE_MOUSE_EVENTS
DebugPrintMouseEvent(event,"Enter",this);
DebugPrintMouseEvent(event,"Enter",this,mWidget);
#endif
AddRef();
@ -1357,7 +1360,7 @@ nsWidget::OnLeaveNotifySignal(GdkEventCrossing * aGdkCrossingEvent)
//
// XXX ramiro - Same as above.
//
if (sButtonMotionTarget != nsnull)
if (nsnull != sButtonMotionTarget)
{
return;
}
@ -1376,7 +1379,7 @@ nsWidget::OnLeaveNotifySignal(GdkEventCrossing * aGdkCrossingEvent)
}
#ifdef TRACE_MOUSE_EVENTS
DebugPrintMouseEvent(event,"Leave",this);
DebugPrintMouseEvent(event,"Leave",this,mWidget);
#endif
AddRef();
@ -1455,7 +1458,7 @@ nsWidget::OnButtonPressSignal(GdkEventButton * aGdkButtonEvent)
InitMouseEvent(aGdkButtonEvent, event, eventType);
#ifdef TRACE_MOUSE_EVENTS
DebugPrintMouseEvent(event,"ButtonPress",this);
DebugPrintMouseEvent(event,"ButtonPress",this,mWidget);
#endif
// Set the button motion target and remeber the widget and root coords
@ -1503,13 +1506,16 @@ nsWidget::OnButtonReleaseSignal(GdkEventButton * aGdkButtonEvent)
InitMouseEvent(aGdkButtonEvent, event, eventType);
#ifdef TRACE_MOUSE_EVENTS
DebugPrintMouseEvent(event,"ButtonRelease",this);
DebugPrintMouseEvent(event,"ButtonRelease",this,mWidget);
#endif
sButtonMotionTarget = nsnull;
if (nsnull != sButtonMotionTarget)
{
sButtonMotionTarget = nsnull;
sButtonMotionRootX = -1;
sButtonMotionRootY = -1;
sButtonMotionRootX = -1;
sButtonMotionRootY = -1;
}
AddRef();

View File

@ -331,13 +331,11 @@ void nsWindow::InitCallbacks(char * aName)
this);
InstallButtonPressSignal(mWidget);
InstallButtonReleaseSignal(mWidget);
InstallMotionNotifySignal(mWidget);
InstallEnterNotifySignal(mWidget);
InstallLeaveNotifySignal(mWidget);
gtk_signal_connect(GTK_OBJECT(mWidget),