Strange artifacts on Windows

70 views
Skip to first unread message

roger tunnicliffe

unread,
Oct 24, 2022, 8:49:14 PM10/24/22
to fltk.general
I have the following initial window.
artifacts1.png

when I click the General Ledger button, I get 
artifacts2.png

You can see the strange artifacts in the original window and half of the text is missing where the 2nd window overlapped it.

I would imagine this would be a difficult bug to track down if one considers the following:
1) Move the 1st window to a different place on the screen then click the General Ledger button and everything is fine.
2) Use the spinner on the 1st window first then  click the General Ledger button and everything is fine.

Has any one reported this previously ? Is there a work around ?
Cheers
Roger

Message has been deleted

Matthias Melcher

unread,
Oct 24, 2022, 8:54:52 PM10/24/22
to fltk.general
As for the ÿÿÿÿÿÿÿ label on top, FLTK assumes that labels use static text. If you delete text after assigning it to a label, you will get random characters from whatever happened to be in memory. To fix that, you can use Fl_Widget::copy_label(...)

I don't know why it only shows half a label on the left. Maybe you re somewhere in a busy loop and FLTK has no chance to refresh the window?

Albrecht Schlosser

unread,
Oct 25, 2022, 12:24:21 PM10/25/22
to fltkg...@googlegroups.com
On 10/25/22 02:49 roger tunnicliffe wrote:
> I have the following initial window.

[image file removed]
>
> when I click the General Ledger button, I get

[image file removed]

>
> You can see the strange artifacts in the original window

(1) As Matt wrote already, the strange "ÝÝÝÝÝÝÝÝÝÝÝ" artifacts (if this
is what you mean) may be caused by a label string going out of scope and
now random text is displayed.

> and half of the text is missing where the 2nd window overlapped it.

(2) This *may* be caused by widgets and their labels (e.g. the two radio
buttons) not being entirely included in their parent group's area. In
this case a redraw might miss some parts of the labels which looks like
it could be the case here.

It could also be caused by a group having a "frame" box type which
doesn't draw its background.

But maybe this (2) is only a follow-up error caused by (1).

I suggest to try to fix bug (1) first, maybe with the help of a memory
access checker like valgrind or address sanitizer.


> I would imagine this would be a difficult bug to track down if one
> considers the following:
> 1) Move the 1st window to a different place on the screen then click
> the General Ledger button and everything is fine.
> 2) Use the spinner on the 1st window first then  click the General
> Ledger button and everything is fine.

Using a memory access checker as said above would likely reveal
something and give hints where to look further. It's definitively worth
a try and will also help in the future.

> Has any one reported this previously ? Is there a work around ?

Such bugs are in many cases user code errors. The workaround is to fix
the bugs (see above how to find them).


roger tunnicliffe

unread,
Oct 26, 2022, 12:57:33 AM10/26/22
to fltk.general
Okay, so I have managed to correct this. I would hazard a guess that the Windows version of fltk has a problem with an overlapping window where certain widgets are involved (good luck trying to debug that !).
The simple fix here is to set the ->hotspot to a different position. It seems by some strange twist of fate I managed to position it exactly at the point and used the exact widgets to make this apparent. 
Complicating this is the fact that you can debug the program and it wont fail (some of the time !!).

Cheers
Roger

  

Albrecht Schlosser

unread,
Oct 26, 2022, 8:42:19 AM10/26/22
to fltkg...@googlegroups.com
On 10/26/22 06:57 roger tunnicliffe wrote:
On Wednesday, October 26, 2022 at 3:24:21 AM UTC+11 Albrecht Schlosser wrote:

Such bugs are in many cases user code errors. The workaround is to fix
the bugs ...


Okay, so I have managed to correct this. I would hazard a guess that the Windows version of fltk has a problem with an overlapping window where certain widgets are involved (good luck trying to debug that !).

That guess is most likely wrong. As I wrote before, such effects are usually caused by errors in user programs.

If it was really a problem in FLTK (which is not entirely impossible), then you should be able to reduce your program to a minimal complete demo that exhibits the error (100 lines or so consisting of only valid FLTK and standard C++ code). If you can post such a program here I promise that we will debug it.

As I wrote before, please take the time to learn how to instrument your program with a memory access checker (I read that "address sanitizer" is available even in Visual Studio). Once you have this working, testing your program will be much easier because you can be sure that there are no illegal memory accesses involved. Did you already consider this?


The simple fix here is to set the ->hotspot to a different position. It seems by some strange twist of fate I managed to position it exactly at the point and used the exact widgets to make this apparent. 
Complicating this is the fact that you can debug the program and it wont fail (some of the time !!).

This all looks like wrong memory access caused by invalid pointers etc.. In such cases changing a tiny piece of code, compiling with debug mode enabled or disabled, or using a debugger can "heal" (hide!) such errors because the memory layout changes and the invalid memory access is no longer obvious. Please believe me: address sanitizer would find such errors and be a great help for your development. Hint: if your program is cross platform you can build it on Linux and run it with valgrind simply like `valgrind my_program` which will also find a lot of memory access errors.

roger tunnicliffe

unread,
Oct 26, 2022, 5:57:22 PM10/26/22
to fltk.general
I guess then that we have a fundamental difference in philosophy. The user is NEVER wrong. It is the programmers job to make sure their programs are sound.
..
if i code:-

cout << *a01_no << " " << a01_name << endl;
win2->(show);

And I can see the No and Name on the console rendered correctly but observe the Window display is corrupt, then anything that goes on in win2->show has got nothing to do with me.

I really like fltk, but every time I have asked a question I have had the response "it's your fault, your doing something wrong"
I won't ask anymore questions.

Michael

unread,
Oct 27, 2022, 7:46:51 AM10/27/22
to fltk.general
I hope that I am allowed to interfere here.
Please do not be disappointed, but Mr. Schlosser is right.
Let me explain.

This is unfortunately a basic problem with the C programming language.
When pointers are passed in somewhere, nothing is copied at first.
That is the job of the next function.

C++ improves a lot here. Unfortunately FLTK is a bit older and works a bit different.
If nothing is copied, then it's also much faster, but you have to be careful.
Memory management in C can be very complicated.

If widgets are named in FLTK, then you have to make sure that the string memory for them always remains valid.
The memory must remain valid until the program is finished.

Everyone here is eager to answer your questions as best as they can.

Matthias Melcher

unread,
Oct 27, 2022, 10:50:08 AM10/27/22
to fltk.general
Well, rogertunnicliffemininest, don't be frustrated. The FL in FLTK stands for Fast and Light. It's fast, because it always assumes you know what you are doing, and it's light because it doesn't copy stuff around that may not need to be copied. We are not trying to be mean here, but we wrote quite extensive documentation to show the compromises that were made. As a result, FLTK runs easily on embedded devices with a few MB or memory. 

As for the diapering labels, just use copy_label() instead of the label() call, or instead of Fl_Button(x, y, w, h, label), use Fl_Button(x, y, w, h); copy_label(dynamic_label); . It's really no big deal, but it helps if you have hundreds of static label texts that are in memory anyway, and FLTK doesn't have to duplicate each and every one (as in (L)ight).

As for the other disappearing labels. You probably have a widget with a label that is outside of its widget boundaries. That is fine, but it needs to be inside the boundaries of teh group that contains the widget. This is made so that a change to a widget redraws only the widget and the label, and not the entire window (as in (F)ast).

The last thing that is often misunderstood: if you set the box type and hence the background to Fl_NO_BOX or one of the ...FRAME types, the group will do oust that and draw nothing as a background. SO if the background becomes dirty because something else draws there (like an outside label), that drawing is not erased. So always make sure that you set the box type of widgets and groups to something that has a background.

And the last thing, which I can't check, because you did not post any source code, Groups and Widgets have to be strictly hierarchical and not overlap. If you have another group overlap some widgets, and that group happens to be drawn last, your widgets that were previously drawn so meticulously, are overdrawn partially by a bare grey background before you even get to see them. 

 - Mathias



Albrecht Schlosser

unread,
Oct 27, 2022, 12:55:10 PM10/27/22
to fltkg...@googlegroups.com
On 10/26/22 23:57 roger tunnicliffe wrote:
> I guess then that we have a fundamental difference in philosophy. The
> user is NEVER wrong. It is the programmers job to make sure their
> programs are sound.

Oh, sorry, this is a misunderstanding. I agree with you 100% in your
explicit wording.

The misunderstanding results from a different point of view: from the
perspective of a library developer (me) the "user" is the user of the
library and thus the "programmer". Sorry for the confusion, I'll try to
be more explicit in the future.

> ..
> if i code:-
>
> cout << *a01_no << " " << a01_name << endl;
> win2->(show);
>
> And I can see the No and Name on the console rendered correctly but
> observe the Window display is corrupt, then anything that goes on in
> win2->show has got nothing to do with me.

As others have tried to explain, this is only partially true. At the
time your `cout` statement is executed, everything is fine. At the time
the next statement `win2->show()` is executed, it's obviously still OK.

But later in your code you will most likely call `Fl::run()` and from
then on the application is running the FLTK event loop, reacting on user
actions with callbacks, timeouts, etc. and that is where your storage
can be overwritten or even a pointer to that storage (as the label()
pointer of a widget) can be overwritten, etc. etc.. This is out of
control of FLTK because your code written elsewhere in your program is
responsible for keeping the pointers and data correct.

This is where I asked you - to help yourself - to investigate how to
instrument your program with a memory access checker like valgrind or
address sanitizer. I did not say that your program is at fault, but that
you should try to test it to help yourself debug your program (*if*
there are any bugs) and help us to help you.

> I really like fltk, but every time I have asked a question I have had
> the response "it's your fault, your doing something wrong"
> I won't ask anymore questions.

That was not my intention, we all want to help all FLTK users (i.e.
programmers) to get their programs working. If you have questions,
please ask here, and we will try to help you.

Others (namely Michael and Matthias) have pointed out what can be wrong
with user programs that cause such effects as you described. Without
(your) code we can only guess what's wrong, and that's what I did: I
guessed. But my and others' experience shows that there are lots of
possibilities to do something wrong in the user code of a FLTK
application and every other C and C++ program.

Such effects as described by you would very likely have been discovered
earlier if they were internal issues (bugs) of the FLTK library. Please
believe me that it is our goal to make the FLTK library as far as
possible error free and help users to work with it successfully.

If you follow our (my) advice and try to reduce your program to a
minimal working demo that shows the error you will see that you either
find a bug in your code or that we will find a bug in FLTK if you post
that short demo code. Without having code we can't help you and others
very well.

And last but not least (I'm repeating myself) please do yourself a
favour and try "address sanitizer" (or "valgrind" on Linux) to find
potential bugs in your program. That's not only a hint for FLTK
development but also for every program everybody develops.

And finally, as a side note, I also use valgrind and address sanitizer
in FLTK development to find memory access bugs - which makes it even
less likely that the effects you describe are FLTK bugs.

I apologize if you got the impression that I (or maybe others) tried to
say "it's your fault" to avoid debugging FLTK. This should not be the
case and was not my intention.

Albrecht Schlosser

unread,
Oct 27, 2022, 1:59:30 PM10/27/22
to fltkg...@googlegroups.com
On 10/26/22 23:57 roger tunnicliffe wrote:
if i code:-

cout << *a01_no << " " << a01_name << endl;
win2->(show);

And I can see the No and Name on the console rendered correctly but observe the Window display is corrupt, then anything that goes on in win2->show has got nothing to do with me.

Hi Roger,

here's another attempt to demonstrate something that can happen and why we're asking for code. This is a contrived example program that uses statements like yours above but does not do what one would expect if you only look at these isolated statements.

The following program should show a box with the label "Hello, World!" - but it fails and shows something else, probably "?? Hello, Bug! ??".

What's going on? The label "a01_name" goes out of scope before the window is eventually shown and the label is drawn. On my system the label "b02_name" is drawn instead but this is implementation dependent (your system may be different). It would be easy to make the label show random data or to make the program crash.

See the comments in the code for how to fix this. Either remove the extra '{ ... }' scope (block) or use copy_label() as Matthias suggested.

Is it FLTK's fault or is it the programmer's fault? That's why we need to see the code.

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <iostream>
using namespace std;
int main(int argc, char **argv) {
Fl_Window *window = new Fl_Window(340, 180);
Fl_Box *box = NULL;
{ // to fix it, comment out or remove this '{'
const char *a01_no = "no";
char a01_name[40] = "Hello, World!"; // a01_name is declared here
box = new Fl_Box(20, 40, 300, 100, a01_name); // a01_name is assigned here
cout << a01_no << ", " << a01_name << endl; // ... and used (printed) here
// box->copy_label(a01_name); // uncommenting this line also fixes the issue
} // to fix it, comment out or remove this '}'
const char *b02_no = "yes";
char b02_name[40] = "?? Hello, Bug! ??";
cout << b02_no << ", " << b02_name << endl;
box->box(FL_UP_BOX);
box->labelsize(25);
window->end();
window->resizable(box);
window->show(argc, argv);
return Fl::run();
}
Output on my system: no, Hello, World! yes, ?? Hello, Bug! ??

  

roger tunnicliffe

unread,
Oct 27, 2022, 5:54:25 PM10/27/22
to fltk.general
The code works fine for me. 
"This is a contrived example program that uses statements like yours above but does not do what one would expect " 
It did exactly what I expected, It screwed up !!

Sorry, but I do not want to spend my time debugging C++ programs. I am looking from a GUI Toolkit that I can use as a front end to my own work.
If I can't simply call it and let it do it's thing then it is not going to be much use.


#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <iostream>
using namespace std;

    Fl_Window *window;
    Fl_Box *box;


    const char *a01_no = "no";
    char a01_name[40] = "Hello, World!";
    const char *b02_no = "yes";
    char b02_name[40] = "?? Hello, Bug! ??";

int main(int argc, char **argv) {

    window = new Fl_Window(340, 180);

        box = new Fl_Box(20, 40, 300, 100, a01_name);
            box->box(FL_UP_BOX);
            box->labelsize(25);
    window->end();

    cout << a01_no << ", " << a01_name << endl;
    cout << b02_no << ", " << b02_name << endl;

    window->resizable(box);
    window->show(argc, argv);
    return Fl::run();

}

imm

unread,
Oct 27, 2022, 7:07:00 PM10/27/22
to General FLTK
On Thu, 27 Oct 2022, 22:54 roger tunnicliffe wrote:


Sorry, but I do not want to spend my time debugging C++ programs. I am looking from a GUI Toolkit that I can use as a front end to my own work.
If I can't simply call it and let it do it's thing then it is not going to be much use.

And that's the problem with C, C++ and the related languages right there, really.

Unless you keep track of the scope, visibility and lifetimes of variables and allocations, especially for things that are stack automatic, then they pretty much always have something unexpected in them when you use them... and particularly in situations like this when the items are being used asynchronously from their creation, often separated by a considerable distance (temporally at runtime and geographically in the source when written/ read.)
The C languages are really bad... It's only 40 odd years of practice that keeps me using them now.

A functional language would probably be better as there are far fewer "side effects" and the loss of mutability resolves a lot of this class of problem. But I find the functional languages "difficult" to comprehend when reasoning about a coding problem. I guess there are no easy answers. That and I don't know of any GUI toolkits that use functional coding anyway.

Rust might be an option though? It's not a functional language but it does have more concrete mechanisms for reasoning about the scope and lifetimes of allocations and their use. And there are Rust bindings for fltk too, of course.

Or some of the interpreted languages might work? I'm thinking Python maybe? It mostly doesn't have this class of bug, and you can use it to cobble up a GUI with fairly limited boilerplate to get things going? In any case I think it'd be less cognitive burden than C++ for this sort of thing, where the front end is not the point of the application anyway - that's kinda why the ML folks are so into Python these days, of course.

Dunno; no easy answers, I guess.
--
Ian
From my Fairphone FP3

roger tunnicliffe

unread,
Oct 27, 2022, 8:52:49 PM10/27/22
to fltk.general
 and just think, in a few years these programs will be driving our cars. !!

<RANT>
To be completely honest, I find C++ to be an abomination. I cannot see any point in building an abstraction of something that is simple anyway. There's bytes, there's word, there's double words and there's quad words. Sometimes those things hold memory address's. Why do we need to abstract that into something that bears little resemblance to how a computer actually works. and the scoping...my god.. if you designate an area of memory to hold something and you don't want to access that outside your current section then DON'T ACCESS IT OUTSIDE YOUR CURRENT SECTION. If you've defined a byte to hold something specific then DON'T ACCESS IT AS A WORD. So hard for everybody ????
And the way C++ moves memory around. I define something in the code and the next minute I find it's moved it to somewhere else. WTF.
</RANT>

"Dunno; no easy answers, I guess.".  The easy answer is don't use a compiler that f&^ks around with your code.




 

Greg Ercolano

unread,
Oct 28, 2022, 1:37:28 AM10/28/22
to fltkg...@googlegroups.com

On 10/27/22 17:52, roger tunnicliffe wrote:

Why do we need to abstract that into something that bears little resemblance to how a computer actually works. and the scoping...my god.. if you designate an area of memory to hold something and you don't want to access that outside your current section then DON'T ACCESS IT OUTSIDE YOUR CURRENT SECTION.

    Look, I've been there -- I knew assembly before I learned C
    and ran into a lot of the same stuff. Very frustrating and not pretty.

    But then it all made sense when I *learned the language first*.

    Someone who watched my histrionics from afar said: "get the C language book"
    which at the time was only one really, the K+R C book linked above.
    And that really brought everything into perspective. Loved the language
    after that, and could see what it brought to the table for assembly programmers.

    I found I could write device drivers and interrupt oriented code in C
    instead of assembly, which was quite wonderful.

    And then about 10 years later when I had to move to C++ to write
    larger programs, and C++ was obviously displacing C for large apps,
    I picked up a book on C++ for C programmers, and then later when
    better books came out, read those too.

    It was absolutely essential to learn the language first.

Matthias Melcher

unread,
Oct 30, 2022, 8:26:53 AM10/30/22
to fltk.general
I agree. The answer that you are looking for is Python. Python stores with every chunk of memory a description what that chunk is and what it does. You never have to worry about bytes, words, doubles or floats again. You can even continue to  use FLTK via pyFLTK.

rogertunnicl...@gmail.com schrieb am Freitag, 28. Oktober 2022 um 02:52:49 UTC+2:
<RANT>
To be completely honest, I find C++ to be an abomination.
</RANT>

Basile Starynkevitch

unread,
Nov 6, 2022, 9:40:21 AM11/6/22
to fltkg...@googlegroups.com


On 10/30/22 13:26, 'Matthias Melcher' via fltk.general wrote:
I agree. The answer that you are looking for is Python. Python stores with every chunk of memory a description what that chunk is and what it does. You never have to worry about bytes, words, doubles or floats again. You can even continue to  use FLTK via pyFLTK.

Or consider also using GNU guile https://www.gnu.org/software/guile/ or even (later, or contribute to it now....) RefPerSys on http://refpersys.org/


Regards from near Paris in France



    


    

-- 
Basile Starynkevitch                  <bas...@starynkevitch.net>
(only mine opinions / les opinions sont miennes uniquement)
92340 Bourg-la-Reine, France
web page: starynkevitch.net/Basile/



Reply all
Reply to author
Forward
0 new messages