Continuously updating a scrolled text widget - Motif

This is a discussion on Continuously updating a scrolled text widget - Motif ; I have a Motif app that monitors text as its produced by another program and displays it in a scrolled text widget. I want the widget to scroll automatically as new text is appended if the end of the existing ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Continuously updating a scrolled text widget

  1. Continuously updating a scrolled text widget

    I have a Motif app that monitors text as its produced by another program and
    displays it in a scrolled text widget. I want the widget to scroll
    automatically as new text is appended if the end of the existing text is
    currently visible. I found that calling XmTextShowPosition every time was
    very inefficient and so I use a time-out proc to cut down on the number of
    calls. I'm testing on x86 Linux 2.4.21 and OpenMotif 2.1.30.

    I've attached an outline of the code I use that shows the Motif calls that
    manipulate the text widget. It works most of the time, but depending
    (apparently) on the width of the text widget or other mysterious factors it
    sometimes gives up scrolling when it shouldn't. This is apparently some
    kind of race condition - if I lengthen the time-out interval from 20ms to
    200ms it seems not to happen (but it doesn't look so good when it is
    working).

    It looks as if XmTextGetLastPosition and/or XmTextPosToXY are giving
    misleading results under some circumstances. Alternatively, there's some
    kind of weird race problem in my code, but I can't see what it is.

    Any suggestions gratefully received.

    Regards,

    Rob.

    The outline code + some more details, in case they are relevant ...

    static Boolean scroll_pending = False;
    static void scroll_out_timeout_proc (XtPointer unused1, XtIntervalId
    *unused2)
    {
    XmTextPosition pos = XmTextGetLastPosition(text_w);
    XmTextShowPosition(text_w, pos);
    scroll_pending = False;
    }
    void scroll_out(char *buf)
    {
    XmTextPosition ins_pos, last_pos;
    Position dontcare;
    Boolean visible;
    int i, j;
    static Boolean last_was_cr = False;
    ins_pos = XmTextGetLastPosition(text_w);
    visible = XmTextPosToXY(text_w, (ins_pos ? ins_pos - 1 : 0),
    &dontcare, &dontcare);
    XmTextInsert(text_w, ins_pos, buf);
    last_pos = XmTextGetLastPosition(text_w);
    /* set up time-out to scroll if insertion position was visible and not
    already set-up */
    if(visible && !scroll_pending) {
    XtAppAddTimeOut(app, 20, scroll_out_timeout_proc, NULL);
    scroll_pending = True;
    }
    XmTextSetInsertionPosition(text_w, last_pos);
    }
    /*

    If I put in some diagnostic print statements, the last call to the time-out
    proc has pos = 30760 (e.g.) and the next call to scroll_out has ins_pos -
    30760 (as it should be), but visible = False (which it shouldn't be since
    the time-out proc just called XmTextShowPosition to make position 30760
    visible).

    The output comes from a pseudo-tty that runs the other program in 8 byte
    blocks using an input callback to read the first block in a burst of output
    and a work proc to read the remainder. The function scroll_out below is
    called once for each block of (up to) 8 bytes and in a sustained burst the
    other program will be trying to write as fast as my app can take it. The
    average transfer is about 5 bytes, but sustained bursts of up to 20 or 30
    consecutive full blocks do happen quite often. About 1 in every 60
    transfers cause the time-out proc to be scheduled.

    */



  2. Re: Continuously updating a scrolled text widget

    I've had much better luck doing this sort of thing a line at a time
    using an XmList (scrolled if you like). Much easier to code, too.

  3. Re: Continuously updating a scrolled text widget

    ST wrote:

    > I've had much better luck doing this sort of thing a line at a time
    > using an XmList (scrolled if you like).


    Thanks, but an XmList doesn't really have anything like the right
    functionality for this application (e.g., it is important for the user to
    be able to do multi-line copies of the text). It also would be unlikely
    perform adequately - my text can grow to many thousands of lines which I
    think you will find will make XmList operations very slow.

    > Much easier to code, too.


    I don't see why you think that - the complexity in my code is to do with
    performance, the actual operations on the text widget are quite
    straightforward.

    Regards,

    Rob.


  4. Re: Continuously updating a scrolled text widget

    Rob Arthan wrote:

    > Thanks, but an XmList doesn't really have anything like the right
    > functionality for this application (e.g., it is important for the user to
    > be able to do multi-line copies of the text).


    An XmList can easily select and copy multiple lines; see the
    primaryOwnership and selectionPolicy resources.

    There is a tradeoff. You lose character-level selection, editing, and
    word-wrapping. I added some context menu items that do select all and
    copies the selection to clipboard (in case the user forgets the standard
    keys).

    > It also would be unlikely
    > perform adequately - my text can grow to many thousands of lines
    > which I think you will find will make XmList operations very slow.


    As for performance, you can believe me or don't. I've coded it both
    ways and have had better luck with a List version.

    > I don't see why you think that - the complexity in my code is to do with
    > performance, the actual operations on the text widget are quite
    > straightforward.


    Implementing a circular buffer is much easier - add a line at bottom,
    and if it's over the limit, delete a line from the top. That's shifting
    a fixed block a known amount. Deleting a line in a text widget requires
    analysis of how many characters to delete.

    You can then decide to scroll based on the line offset, instead of
    analyzing pixels, which is slow, since text might have uniform height
    and width.

  5. Re: Continuously updating a scrolled text widget

    ST wrote:

    > Rob Arthan wrote:
    >
    >> Thanks, but an XmList doesn't really have anything like the right
    >> functionality for this application (e.g., it is important for the user to
    >> be able to do multi-line copies of the text).

    >
    > An XmList can easily select and copy multiple lines; see the
    > primaryOwnership and selectionPolicy resources.
    >
    > There is a tradeoff. You lose character-level selection, editing, and
    > word-wrapping. I added some context menu items that do select all and
    > copies the selection to clipboard (in case the user forgets the standard
    > keys).
    >
    > > It also would be unlikely
    > > perform adequately - my text can grow to many thousands of lines
    > > which I think you will find will make XmList operations very slow.

    >
    > As for performance, you can believe me or don't. I've coded it both
    > ways and have had better luck with a List version.
    >
    >> I don't see why you think that - the complexity in my code is to do with
    >> performance, the actual operations on the text widget are quite
    >> straightforward.

    >
    > Implementing a circular buffer is much easier - add a line at bottom,
    > and if it's over the limit, delete a line from the top. That's shifting
    > a fixed block a known amount. Deleting a line in a text widget requires
    > analysis of how many characters to delete.
    >
    > You can then decide to scroll based on the line offset, instead of
    > analyzing pixels, which is slow, since text might have uniform height
    > and width.


    Thanks again, but XmList really doesn't have the functionality that I need -
    I do need the word-wrapping option, character-by-character selection,
    response to typed input, etc. I don't need to implement a circular buffer
    in the sense that you mean (I chop away a percentage of the text if its
    total size grows over a limit - this is easy to code and gives negligible
    performance overhead). The scrolled text widget automatically does all the
    line offset stuff - it just seems to be getting something wrong in a very
    tiny fraction of cases (actually rather rare ones in which the user has
    made the text widget unusually narrow).

    You say you have had more "luck" with XmList, but my app has been giving
    pretty adequate service for over 10 years. I was really looking for an
    explanation of quite rare unexpected behaviour of the existing design
    rather than encouragement to change the design completely.

    If anyone can give any insight into the apparent problem with XmTextPosToXY
    seemingly returning false when it shouldn't, I would be very grateful.

    Regards,

    Rob.


  6. Re: Continuously updating a scrolled text widget

    Sorry, I didn't realize this was existing code.

    Looking at the source code (you do have the source, right?) itfunction
    will return false if the line maps to nothing, or the line is greater
    than the number of lines in the widget.

    It obtains the line by calling _XmTextPosToLine which you can probably
    call and print out for debugging.

+ Reply to Thread