Strange artefacts visible on controls

33 views
Skip to first unread message

Jck_01

unread,
Jul 6, 2022, 6:54:21 AM7/6/22
to fltk.general
Hello,
I create the application with the FLTK library. Almost everything works as it should, except one important thing, and  I couldn't find the right solution so far. Random artifacts appear in the window. They also appear randomly - sometimes everything is displayed correctly, but sometimes there are strange lines, some parts of the controls are not refreshed etc. I tried to use Fl::check() but it didn't help in every case. Please see the included examples (a strange black line over the window, a strange blue line over the button, and a broken frame around the button). How can I avoid these problems?
artefact1.JPG
artefact2.JPG
artefact3.JPG

imm

unread,
Jul 6, 2022, 7:00:45 AM7/6/22
to General FLTK
On Wed, 6 Jul 2022 at 11:54, Jck_01 wrote:
Hello,
I create the application with the FLTK library. Almost everything works as it should, except one important thing, and  I couldn't find the right solution so far. Random artifacts appear in the window. They also appear randomly - sometimes everything is displayed correctly, but sometimes there are strange lines, some parts of the controls are not refreshed etc. I tried to use Fl::check() but it didn't help in every case. Please see the included examples (a strange black line over the window, a strange blue line over the button, and a broken frame around the button). How can I avoid these problems?

We'd probably have to see some code to tell, but to me it looks like you are drawing outside the valid context.

Hmm; Is this on Windows?
The order and setting of the "pens" in Windows is a bit sensitive, so you need to ensure you do that in the correct order too. I think that is discussed in the docs, FWIW.
Maybe you can post a small, compile-able example that shows what you are doing that  gets this effect?


Jck_01

unread,
Jul 6, 2022, 7:58:34 AM7/6/22
to fltk.general
środa, 6 lipca 2022 o 13:00:45 UTC+2 Ian MacArthur napisał(a):
On Wed, 6 Jul 2022 at 11:54, Jck_01 wrote:
Hello,
I create the application with the FLTK library. Almost everything works as it should, except one important thing, and  I couldn't find the right solution so far. Random artifacts appear in the window. They also appear randomly - sometimes everything is displayed correctly, but sometimes there are strange lines, some parts of the controls are not refreshed etc. I tried to use Fl::check() but it didn't help in every case. Please see the included examples (a strange black line over the window, a strange blue line over the button, and a broken frame around the button). How can I avoid these problems?

We'd probably have to see some code to tell, but to me it looks like you are drawing outside the valid context.

Hmm; Is this on Windows?

Yes, this is on Windows 10.

The order and setting of the "pens" in Windows is a bit sensitive, so you need to ensure you do that in the correct order too. I think that is discussed in the docs, FWIW.
Maybe you can post a small, compile-able example that shows what you are doing that  gets this effect?

 I will show only most important parts of the code since it involves many classes and is quite complicated.

First I create the dialog window as the new class where inside I define the pointer to the Fl_window.
using WindowPtr = std::unique_ptr<Fl_Window>;
WindowPtr windowPtr;

Then, in the class I create the controls, for example:
windowPtr = std::make_unique<Fl_Window>(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

connectToServerButton = std::make_unique<Fl_Button>(20, 268, 200, 30, nullptr);
connectToServerButton->copy_label(gui.getTranslation().Translate(u8"Connect to server").c_str());
connectToServerButton->callback(connectToServerCallback, this);

windowPtr->end();



Then, in the connectToServerCallback() callback I do following (netMessages is a multiline edit control):

netMessages->value(u8"");
addMessage(gui.getTranslation().Translate(u8"Connecting to server..."));
Fl::check();
int ret = gui.getNet().getClient().start(); // starting the network client
if (ret != Network::NET_OK) // error
{
}
else // client connected to server
{
  addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());
  connectToServerButton->deactivate();
}



When I click the connectToServerButton, I sometime receive the artifacts on the whole dialog or on button.

imm

unread,
Jul 6, 2022, 8:05:30 AM7/6/22
to General FLTK
On Wed, 6 Jul 2022 at 12:58, Jck_01 wrote:
>
>
> When I click the connectToServerButton, I sometime receive the artifacts on the whole dialog or on button.
>

I was rather hoping to dee more of your widget code and in particular
what you are doing for draw() methods, that sort of thing.
There's not enough here to express any useful opinion.

How many threads are in your code?
Some of what you are seeing looks a lot like it might be thread
related rendering artefacts, if the code is not thread safe (though
that's just a guess as there's not really enough here to know.)

Jck_01

unread,
Jul 6, 2022, 11:04:03 AM7/6/22
to fltk.general

I was rather hoping to dee more of your widget code and in particular
what you are doing for draw() methods, that sort of thing.

I don't use any draw() methods, just ordinary creation of controls like buttons etc. Nothing special at all.
 

How many threads are in your code?

Generally only one. The code in dialog windows uses one, main program thread. A new thread is created only when I call methods of network library. Could it be the reason of artefacts?

Albrecht Schlosser

unread,
Jul 6, 2022, 11:18:17 AM7/6/22
to fltkg...@googlegroups.com
On 7/6/22 16:04 Jck_01 wrote:


How many threads are in your code?

Generally only one. The code in dialog windows uses one, main program thread. A new thread is created only when I call methods of network library. Could it be the reason of artefacts?

Generally not if you don't call FLTK methods from within your thread code.

Here's another question: Did you recently update your FLTK repo / working copy? Maybe even switching from 1.3 to 1.4 ?

The reason I'm asking this is because mixing library headers (old vs. new) and maybe compiling only parts of the library could have similar effects (although maybe not with random appearance). Anyway, I suggest to remove old FLTK installations from your system (if there are any) and make sure that you compile your entire FLTK lib *and* your entire application (make clean; make; or whatever is applicable) to be sure everything is built from one FLTK source.

If this doesn't help, we'd really need code (a short, compileable example source file) and more information about your FLTK version and build environment.

imm

unread,
Jul 6, 2022, 11:35:09 AM7/6/22
to General FLTK
On Wed, 6 Jul 2022 at 16:04, Jck_01 wrote:
>
>>
>> How many threads are in your code?
>
> Generally only one. The code in dialog windows uses one, main program thread. A new thread is created only when I call methods of network library. Could it be the reason of artefacts?
>

It depends...
If the network threads do not interact with the FLTK widgets then
there is no problem.
However, if the worker thread DOES interact with FLTK widgets, then
that will be a problem... At that point you need to determine how to
best make your network thread interact safely with the GUI render
context. The "Advanced FLTK" section of the manual addresses those
issues, either via locking (probably not a good idea in a network
thread) or via the FL::awake() callback mechanism.

Mohammed

unread,
Jul 6, 2022, 11:41:23 AM7/6/22
to fltkg...@googlegroups.com
Wouldn’t using std::unique_ptr interfere with FLTK’s parent/child ownership system. If a unique_ptr fell out if scope it would call delete on the pointer and this might lead to issues. 

Sent from my iPhone

On 6 Jul 2022, at 18:04, Jck_01 <projekt...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/12b02a13-f934-4f1d-bd94-6a15501de17dn%40googlegroups.com.

imm

unread,
Jul 6, 2022, 11:48:12 AM7/6/22
to General FLTK
On Wed, 6 Jul 2022 at 16:41, Mohammed wrote:
>
> Wouldn’t using std::unique_ptr interfere with FLTK’s parent/child ownership system. If a unique_ptr fell out if scope it would call delete on the pointer and this might lead to issues.
>

Hi Mo,
Yes, that's a fair point.
I was kind of assuming the pointer was instantiated in some "global"
scope, but that may not be the case...

Jck_01

unread,
Jul 6, 2022, 12:43:30 PM7/6/22
to fltk.general

Generally not if you don't call FLTK methods from within your thread code.

My network library uses the boost.asio library and doesn't interact with FLTK.

Here's another question: Did you recently update your FLTK repo / working copy? Maybe even switching from 1.3 to 1.4 ?

No, I use the FLTK 1.3.8 for a long time. It was recompiled from the scratch.
 

Jck_01

unread,
Jul 6, 2022, 12:43:50 PM7/6/22
to fltk.general
It is instantiated in the dialog window object which in turn is instantiated in the object of a main window so it will never fell out of a scope when the program runs.

Jck_01

unread,
Jul 7, 2022, 12:05:43 PM7/7/22
to fltk.general
Hello, I have found the code which makes the artefacts on the screen. There is a callback method which is called when the button is pressed. In this callback I call the network function of a boost/asio library. This function writes data to the server. It is just boost::asio::async_write call. When I commented out this call, everything was OK - no artefacts at all. So the artefacts are generated by boost::asio::async_write. It's strange since my network library doesn't use FLTK at all!

Ian MacArthur

unread,
Jul 7, 2022, 1:59:27 PM7/7/22
to Fltk General
On 7 Jul 2022, at 15:10, Jck_01 wrote:
>
> Hello, I have found the code which makes the artefacts on the screen. There is a callback method which is called when the button is pressed. In this callback I call the network function of a boost/asio library. This function writes data to the server. It is just boost::asio::async_write call. When I commented out this call, everything was OK - no artefacts at all. So the artefacts are generated by boost::asio::async_write. It's strange since my network library doesn't use FLTK at all!

That sounds most curious - if the async call is not interacting with fltk at all, I’d expect it to be “safe”, so this is unexpected. Does it (the async method) interact with the GUI context in some way, or something?

It might be useful if you could show us the code for the callback, in case something useful occurs to anyone on seeing it...


Albrecht Schlosser

unread,
Jul 7, 2022, 2:06:00 PM7/7/22
to fltkg...@googlegroups.com
On 7/7/22 16:10 Jck_01 wrote:
> Hello, I have found the code which makes the artefacts on the screen.
> There is a callback method which is called when the button is pressed.
> In this callback I call the network function of a boost/asio library.
> This function writes data to the server. It is just
> boost::asio::async_write call. When I commented out this call,
> everything was OK - no artefacts at all. So the artefacts are
> generated by boost::asio::async_write.

Thanks for the feedback, and it's great that you found the cause.

> It's strange since my network library doesn't use FLTK at all!

Yes, such effects shouldn't happen. There's one "standard" error though
that a wild pointer or another pointer going out of scope overwrites
some "random" memory bits and this causes the bugs eventually, sometimes
this happens much later than the original bug. I know, it's a wild
guess, but often this is the reason for such random errors.

I'd recommend to run your program with some memory access checkers
enabled. On Linux (if you can build it there) this would for instance be
'valgrind' but I can't help with Windows if that's the only platform you
can build your program on. Maybe someone else can help you better.

Gonzalo Garramuño

unread,
Jul 7, 2022, 5:31:55 PM7/7/22
to fltkg...@googlegroups.com

On 7/7/22 15:05, Albrecht Schlosser wrote:
> I'd recommend to run your program with some memory access checkers
> enabled. On Linux (if you can build it there) this would for instance
> be 'valgrind' but I can't help with Windows if that's the only
> platform you can build your program on. Maybe someone else can help
> you better.
>
On Linux and macOS, you also have the option of using address santizer
(asan), which I found much better (and faster) than valgrind, but it
requires a debug recompilation of your code.

On Windows, you have Deleaker which is a commercial application but
offers a 14-day trial.

Gonzalo Garramuño

unread,
Jul 7, 2022, 5:39:45 PM7/7/22
to fltkg...@googlegroups.com
I just found out address sanitizer is available for the latest MSVC too:

https://devblogs.microsoft.com/cppblog/addresssanitizer-asan-for-windows-with-msvc/

I have not tried it, but it should work like the macOS/Linux one.


Jck_01

unread,
Jul 8, 2022, 2:47:48 AM7/8/22
to fltk.general

That sounds most curious - if the async call is not interacting with fltk at all, I’d expect it to be “safe”, so this is unexpected. Does it (the async method) interact with the GUI context in some way, or something?

As far as I know - it doesn't at all.
 

It might be useful if you could show us the code for the callback, in case something useful occurs to anyone on seeing it...

The  connectToServer() callback calls  gui.getNet().sendMessage(NetProtocol::MsgHello::ID), which calls sendMessage(nullptr, id), which calls  getClient().write(msg.encode()), which calls session->write().

void GUIDlgNetClient::connectToServer(void)
{
    srvIPAddressInput->deactivate();
    srvPortInput->deactivate();

    netMessages->value(u8"");
    addMessage(gui.getTranslation().Translate(u8"Connecting to server..."));
    Fl::check();
    int ret = gui.getNet().getClient().start();
    if (ret != Network::NET_OK)
    {
        addMessage(GUI::translateErrorCode(ret));
        if (gui.getNet().getClient().isActive())
            gui.getNet().getClient().stop();
    }
    else
    {
        addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());
         
        gui.getNet().sendMessage(NetProtocol::MsgHello::ID); // <<<<<< This line makes the artifacts!
    }
   

}

bool Network::sendMessage(const unsigned char id)
{
  return sendMessage(nullptr, id);
}
     
bool Network::sendMessage(const SessionPtr session, const unsigned char id)
{
 
    switch (id)
    {
        case NetProtocol::MsgHello::ID:
        {
           NetProtocol::MsgHello msg;

           getClient().write(msg.encode());
           break;
        }
          case .....
          case .....

          .....
}          

void NetClient::write(std::string msg)
{
    session->addMessage(msg);
    if (session->canWrite())
        session->write();
}

void NetSession::write(void)
{
    boost::asio::async_write(*socket.get(),
        boost::asio::buffer(writeQueue.front()),
        [&](boost::system::error_code error, std::size_t bytesTransferred)
        {
            if (!error)
            {
                writeQueue.pop();
                if (!writeQueue.empty())
                    write();
            }
            else
            {
                auto err = error;
                netConnector.getErrorHandler()(shared_from_this(), err);
            }
        }
    );
}
 

wea...@gmail.com

unread,
Jul 8, 2022, 3:32:05 AM7/8/22
to fltk.general
Hi
void GUIDlgNetClient::connectToServer(void)
{
    srvIPAddressInput->deactivate();
    srvPortInput->deactivate();

    netMessages->value(u8"");
    addMessage(gui.getTranslation().Translate(u8"Connecting to server..."));
    Fl::check();
    int ret = gui.getNet().getClient().start();
    if (ret != Network::NET_OK)
    {
        addMessage(GUI::translateErrorCode(ret));
        if (gui.getNet().getClient().isActive())
            gui.getNet().getClient().stop();
    }
    else
    {
        addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());
Just an idea, but maybe the problem is here ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^. Maybe it operates on temporary objects or takes the pointer produced by c_str() and the problem is in the pointer handling? Just guessing. 

Jck_01

unread,
Jul 8, 2022, 6:52:51 AM7/8/22
to fltk.general

    {
        addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());

Just an idea, but maybe the problem is here ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^. Maybe it operates on temporary objects or takes the pointer produced by c_str() and the problem is in the pointer handling? Just guessing. 
 
  It's strange but I found another line which created the artifacts, and this line used the FLTK GUI. Namely, at the end of the callback for the startButton I used the following line:
startButton->deactivate();

(the startButton is of type Fl_Button)

When I commented out this line, evertything started to work correctly, no artifacts. So I moved this line before following line:
addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());

So now the code looks like this:
startButton->deactivate();
addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());


Now there are no artifacts at all. The addMessage() method is following:
void GUIDlgNetClient::addMessage(std::string msg)
{
    netMessages->insert(msg.c_str());
    netMessages->insert(u8"\n");
    Fl::check();
}

The netMessages is definied like this:
using FlMultilineOutputPtr = std::unique_ptr<Fl_Multiline_Output>;
FlMultilineOutputPtr netMessages;


Seems there is a strange coincidence between the Fl_Multiline_Output (netMessages) and the Fl_Button (startButton). If I write something to Fl_Multiline_Output, and then disable the button, I get the artifacts. When I first disable the button and then write to Fl_Multiline_Output, everything is OK.
       

imm

unread,
Jul 8, 2022, 7:03:51 AM7/8/22
to General FLTK
On Fri, 8 Jul 2022 at 07:48, Jck_01 wrote:
>
>> That sounds most curious - if the async call is not interacting with fltk at all, I’d expect it to be “safe”, so this is unexpected. Does it (the async method) interact with the GUI context in some way, or something?
>
>
> As far as I know - it doesn't at all.
>

OK... well, that was my best guess, so I'm at something of a loss as
to what to try next!

It is increasingly looking like some sort of dangling pointer issue,
as Albrecht (and others) have suggested.
Which might be a hard thing to debug...

imm

unread,
Jul 8, 2022, 7:16:01 AM7/8/22
to General FLTK
On Fri, 8 Jul 2022 at 11:52, Jck_01 wrote:
>
> It's strange but I found another line which created the artifacts, and this line used the FLTK GUI. Namely, at the end of the callback for the startButton I used the following line:
> startButton->deactivate();
>

Oh dear, that is odd.
Simply deactivating a button from within the callback should not have
any "odd" side effects.
And you are sure the fltk context is only being manipulated from the
main() thread?

Unless it is a dangling pointer issue, the only way I can think to get
these sort of weird effects is modifying the graphics context from a
non-main() thread context, which it seems you are not doing.



> So now the code looks like this:
> startButton->deactivate();
> addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());
>
> Now there are no artifacts at all. The addMessage() method is following:
> void GUIDlgNetClient::addMessage(std::string msg)
> {
> netMessages->insert(msg.c_str());
> netMessages->insert(u8"\n");
> Fl::check();
> }

And this all happens in the context of the main() thread?
For example, it is never safe to call Fl::check(); from any non-main
thread context.

Actually, if this is all happening in the callback, I'd not call
Fl::check(); at all anyway, TBH.

Jck_01

unread,
Jul 8, 2022, 10:08:54 AM7/8/22
to fltk.general


And this all happens in the context of the main() thread?
For example, it is never safe to call Fl::check(); from any non-main
thread context.

Actually, if this is all happening in the callback, I'd not call
Fl::check(); at all anyway, TBH.

I did another test. I kept the instructions order original, i.e. first  addMessage(), and then  startButton->deactivate(), but after this I called Fl::check() - and this removed the artifacts!
addMessage(gui.getTranslation().Translate(u8"Connected!").c_str());
startButton->deactivate();
Fl::check(); <<<<< THIS HELPED IN REMOVING THE ARTIFACTS



Reply all
Reply to author
Forward
0 new messages