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:
parent
41f30ca064
commit
ce703464bd
@ -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 |
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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__
|
||||
|
||||
@ -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 |
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user