Button flashes (disappears) when changing its sensitivity - Motif
This is a discussion on Button flashes (disappears) when changing its sensitivity - Motif ; Hi,
I am having a lot of trouble figuring out a problem I am seeing in my
Motif gui. I have a set of pushbuttons, each with a pixmap, on my main
window. When a state change occurs in my ...
-
Button flashes (disappears) when changing its sensitivity
Hi,
I am having a lot of trouble figuring out a problem I am seeing in my
Motif gui. I have a set of pushbuttons, each with a pixmap, on my main
window. When a state change occurs in my software, I dim or undim
various pushbuttons to show they are now available/unavailable. I am
using XtSetSensitive() to change the sensitivity of the pushbuttons.
For some reason, each time I call XtSetSensitive() for a pushbutton,
the entire pushbutton completely disappears from the window for about
1/2 second, then it gets redrawn with its new sensitivity. I am not
asking for the pushbutton to be redrawn, I am simply calling
XtSetSensitive(). The flash that this causes is really distracting.
It looks really strange when more than one pushbutton disappears at
once.
I notice someone else had this same problem once and an XFlush() was
recommended. I tried calling XFlush() directly after calling
XtSetSensitive(), thinking it might be some kind of delay in processing
it, but this seemed to have no effect. (it didn't work for the other
guy either)
I am confused because I have another Motif gui that also has a set of
pushbuttons, each with a pixmap, and when sensitivity is changed on
those pushbuttons, I don't see a flash.
This has me baffled.
Can anyone offer any suggestions?
Thank you!
Julie
-
Re: Button flashes (disappears) when changing its sensitivity
I'd remove the XFlush call unless you're sure what you're doing. This
usually happens when the application is busy doing something (e.g.,
writing to a file, or waiting for something) and not servicing expose
events quickly enough.
Classic example: you have a menu button callback that saves a file.
Clicking on the button causes the menu to disappear, and call your
application callback. In the callback you write a 5GB file that takes a
few minutes. During all that time, you never return out of the
callback, so none of the widgets redraw all the damaged area underneath
the menu.
In this case, it would seem that you want the system to redraw the area
under the menu before going off and writing the file. And you can do
that, with XmUpdateDisplay.
But this is only addressing the symptom, not the problem. Move another
unrelated window over your app, and it will be damaged and not redrawn.
The real problem is the UI is dead, because the event loop is starved.
Some folks will pepper in lots of calls to XmUpdateDisplay all over the
place. But now you have to write some bytes here, update, write some
more bytes, update, and... well, what happens if it the call blocks
because it's NFS? It's still dead.
It is possible you're not starving the event loop, but it's the first
place I'd look.
-
Re: Button flashes (disappears) when changing its sensitivity
"Julie" wrote in message
news:1157645128.494282.100830@b28g2000cwb.googlegr oups.com...
> Hi,
> I am having a lot of trouble figuring out a problem I am seeing in my
> Motif gui. I have a set of pushbuttons, each with a pixmap, on my main
> window. When a state change occurs in my software, I dim or undim
> various pushbuttons to show they are now available/unavailable. I am
> using XtSetSensitive() to change the sensitivity of the pushbuttons.
>
> For some reason, each time I call XtSetSensitive() for a pushbutton,
> the entire pushbutton completely disappears from the window for about
> 1/2 second, then it gets redrawn with its new sensitivity. I am not
> asking for the pushbutton to be redrawn, I am simply calling
> XtSetSensitive(). The flash that this causes is really distracting.
> It looks really strange when more than one pushbutton disappears at
> once.
>
> I notice someone else had this same problem once and an XFlush() was
> recommended. I tried calling XFlush() directly after calling
> XtSetSensitive(), thinking it might be some kind of delay in processing
> it, but this seemed to have no effect. (it didn't work for the other
> guy either)
>
> I am confused because I have another Motif gui that also has a set of
> pushbuttons, each with a pixmap, and when sensitivity is changed on
> those pushbuttons, I don't see a flash.
>
> This has me baffled.
>
> Can anyone offer any suggestions?
> Thank you!
> Julie
>
If your Pushbuttons were only of labelType XmSTRING, then the only thing you
would need to do is call XFlush after calling XtSetSensitive, regardless of
what
else happens in your callback.
However, since you are using labelType=XmPIXMAP, that changes things.
When you call XtSetSensitive(), it calls XtSetValues(), which asks the
button to redraw itself. But it now has to change pixmaps from the
labelPixmap
to the labelInsensitivePixmap, instead of just redrawing the text. To do
this,
Lable invokes XCopyArea, which causes an expose event. The widget will
be blank until that event is processed from the event queue.
Therefore, if your callback does a lot of work before returning, your GUI
is frozen. One way to get around this is to have your callback make any
necessary GUI changes (calling XtSetSensitive, etc.), then call
XmUpdateDisplay before doing anything that will burn up time.
Or you can register a WorkProc to do the part that will take some time.
That way, the GUI gets updated before the WorkProc gets executed.
This is especially useful if the time-consuming task contains a loop that is
called many times; the WorkProc can be keep itself active repeatedly instead
of
using a loop, thus updating the GUI for each pass.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
-
Re: Button flashes (disappears) when changing its sensitivity
Thank you both so much for your help!
I didn't think I was doing anything labor intensive since my gui is
pretty much a pure gui. But it does call an API function to check for
messages from an external process and that did, indeed, turn out to be
the culprit. I never would have checked for this without both of you
pointing me in that direction so thank you tremendously!
The API function I am calling has a millisecond timeout that was
actually getting interpreted as a microsecond timeout (1000x longer!)
which was a bug -- so the message check routine which does a select()
call was hanging for much longer than expected, but it was only
noticeable when the pixmap buttons were waiting to be redrawn from the
expose event.
Thanks also, Fred, for your explanation of what happens when a pixmap
button is made insensitive since I didn't know it resulted in an
XCopyArea and an expose event. I also never knew the difference
between an XFlush() and an XmUpdateDisplay() so that was very
enlightening.
Thank you again!
Julie
Fred Kleinschmidt wrote:
> "Julie" wrote in message
> news:1157645128.494282.100830@b28g2000cwb.googlegr oups.com...
> > Hi,
> > I am having a lot of trouble figuring out a problem I am seeing in my
> > Motif gui. I have a set of pushbuttons, each with a pixmap, on my main
> > window. When a state change occurs in my software, I dim or undim
> > various pushbuttons to show they are now available/unavailable. I am
> > using XtSetSensitive() to change the sensitivity of the pushbuttons.
> >
> > For some reason, each time I call XtSetSensitive() for a pushbutton,
> > the entire pushbutton completely disappears from the window for about
> > 1/2 second, then it gets redrawn with its new sensitivity. I am not
> > asking for the pushbutton to be redrawn, I am simply calling
> > XtSetSensitive(). The flash that this causes is really distracting.
> > It looks really strange when more than one pushbutton disappears at
> > once.
> >
> > I notice someone else had this same problem once and an XFlush() was
> > recommended. I tried calling XFlush() directly after calling
> > XtSetSensitive(), thinking it might be some kind of delay in processing
> > it, but this seemed to have no effect. (it didn't work for the other
> > guy either)
> >
> > I am confused because I have another Motif gui that also has a set of
> > pushbuttons, each with a pixmap, and when sensitivity is changed on
> > those pushbuttons, I don't see a flash.
> >
> > This has me baffled.
> >
> > Can anyone offer any suggestions?
> > Thank you!
> > Julie
> >
>
> If your Pushbuttons were only of labelType XmSTRING, then the only thing you
> would need to do is call XFlush after calling XtSetSensitive, regardless of
> what
> else happens in your callback.
>
> However, since you are using labelType=XmPIXMAP, that changes things.
> When you call XtSetSensitive(), it calls XtSetValues(), which asks the
> button to redraw itself. But it now has to change pixmaps from the
> labelPixmap
> to the labelInsensitivePixmap, instead of just redrawing the text. To do
> this,
> Lable invokes XCopyArea, which causes an expose event. The widget will
> be blank until that event is processed from the event queue.
>
> Therefore, if your callback does a lot of work before returning, your GUI
> is frozen. One way to get around this is to have your callback make any
> necessary GUI changes (calling XtSetSensitive, etc.), then call
> XmUpdateDisplay before doing anything that will burn up time.
>
> Or you can register a WorkProc to do the part that will take some time.
> That way, the GUI gets updated before the WorkProc gets executed.
> This is especially useful if the time-consuming task contains a loop that is
> called many times; the WorkProc can be keep itself active repeatedly instead
> of
> using a loop, thus updating the GUI for each pass.
> --
> Fred L. Kleinschmidt
> Boeing Associate Technical Fellow
> Technical Architect, Software Reuse Project