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 ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Button flashes (disappears) when changing its sensitivity

  1. 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


  2. 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.

  3. 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



  4. 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



+ Reply to Thread