Application window refreshing only on mouse movement. Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Application window refreshing only on mouse movement.

Post by Ksawery »

Hello,

I've developed a multithreaded wxWidgets application on a Linux platform. The application uses a few detached threads for fetching new data from local devices or the network, and a single thread to queue events in the "main" loop, which then updates the display via event handlers. Data is shared between the threads using wxCriticalSectionLocker(s) where necessary. Each thread contains a different delay, to avoid locking/timing issues.

The application works well, however, I've run into a problem, where the main application window is not refreshed until the mouse is moved. I've searched through several forums, which mainly suggested explicitly using Update() and Refresh() in the main window event handler. Initially, this seemed to work, however, now the issue has returned. I'm still not sure what might be causing the problem, as it occurs irregularly.

New data is displayed in the application via wxStaticText(s) and wxStaticBitmap(s). These are also shown or hidden as needed. User control is made available via wxTextCtrl(s) and wxButton(s).

I would appreciate any help in fixing this issue.

Best regards,
Ksawery
Kvaz1r
Super wx Problem Solver
Super wx Problem Solver
Posts: 357
Joined: Tue Jun 07, 2016 1:07 pm

Re: Application window refreshing only on mouse movement.

Post by Kvaz1r »

As usual - could you provide minimal but reproducible sample? Does the behaviour exists only in multithreading apps? What exactly version of the library?
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Application window refreshing only on mouse movement.

Post by doublemax »

Which exact Linux version/distro, window manager, wxWidgets version are you using?

Does wxWidgets use GTK2 or GTK3?

There are a few things you can do to further narrow down the error.

1) use logging inside the threads and the event handlers that change the gui to check if everything works as intended (is the code that updates the gui executed when it should, or only when the mouse moves)

2) does the mouse need to be over your application window in order to update the gui, or can it also be outside?

2a) if it needs to be over your application, what happens if you drag a window from another application across yours? Does it refresh the GUI?
Each thread contains a different delay, to avoid locking/timing issues.
This sounds suspicious. wxCriticalSections, wxMutex etc. should take care of that. Delays will be unreliable over time.
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Application window refreshing only on mouse movement.

Post by ONEEYEMAN »

Hi,
In addition - what theme do you use?

Thank you.
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Re: Application window refreshing only on mouse movement.

Post by Ksawery »

Thank you for your replies. As I'm not currently in the office, I can't answer all your questions, however, I can answer the following:
Does wxWidgets use GTK2 or GTK3?
I'm using wxWidgets version 3.1.4, with GTK3.
In addition - what theme do you use?
Latest version of Ubuntu Cinnamon Remix, with the Kimmo-Light theme.
1) use logging inside the threads and the event handlers that change the gui to check if everything works as intended (is the code that updates the gui executed when it should, or only when the mouse moves)
I will need to double-check this when I'm in the office.
2) does the mouse need to be over your application window in order to update the gui, or can it also be outside?
I think that the window is updated regardless of the mouse position, however, I would also need to double-check this.
This sounds suspicious. wxCriticalSections, wxMutex etc. should take care of that. Delays will be unreliable over time.
Do you believe that adding delays at the end of each thread might be the culprit? I wanted to avoid queuing events too frequently in the main thread, as the event handler might not be able to keep up. Currently, window refresh events are delayed by 200ms. Would you recommend replacing these with minimal delays?
Does the behaviour exists only in multithreading apps?
So far I've only noticed the problem in the multithreaded application.
As usual - could you provide minimal but reproducible sample?
Here is the thread that queues events in the main loop (depending on application mode, it either sends events to an error window or the main window):

Code: Select all

#include "cThreadRefreshDisplay.h"

DEFINE_EVENT_TYPE(wxEVT_DISPLAY_UPDATE)

cThreadRefreshDisplay::cThreadRefreshDisplay(cMain* pMain, cMainError* pMainError, bool bErrorMode) : wxThread(wxTHREAD_DETACHED)
{
	this->pMain = pMain;
	this->pMainError = pMainError;
	this->bErrorMode = bErrorMode;
}

cThreadRefreshDisplay::~cThreadRefreshDisplay()
{
	if (!bErrorMode) pMain->threadRefreshDisplay = NULL;
	else pMainError->threadRefreshDisplay = NULL;
}

wxThread::ExitCode cThreadRefreshDisplay::Entry()
{
    while (!TestDestroy())
    {
    	if (bErrorMode)
    	{
    		if (pMainError != NULL)
		{
			//Send event to main window
 			wxCommandEvent* evt = new wxCommandEvent(wxEVT_DISPLAY_UPDATE, wxID_ANY);
			((wxEvtHandler*) pMainError)->QueueEvent(evt);
		}
    	}
    	else
    	{
    		if (pMain != NULL)
		{
			//Send event to main window
			wxCommandEvent* evt = new wxCommandEvent(wxEVT_DISPLAY_UPDATE, wxID_ANY);
			((wxEvtHandler*) pMain)->QueueEvent(evt);
		}
    	}

    	wxThread::Sleep(DELAY_REFRESH_DISPLAY); // 211ms delay
    }

    return (wxThread::ExitCode) 0;
}
Here is the event handler that refreshes the display (partially in pseudo-code):

Code: Select all

void cMain::RefreshDisplay(void)
{
	{
		wxCriticalSectionLocker local_lock(mbMaster->local_guard);

		// FETCH SHARED DATA
	}

	// CHECK IF APPLICATION MODE CHANGED
	
		// IF CHANGED, DELETE AND RE-DRAW SEVERAL ELEMENTS, INCLUDING:
		// PANELS, STATIC BITMAPS, STATIC TEXTS, TEXT INPUTS AND BUTTONS.
		
		// IF UNCHANGED, UPDATE EXISTING ELEMENTS, INCLUDING 
		// STATIC BITMAPS, STATIC TEXTS AND TEXT INPUTS

	// REFRESH AND UPDATE FRAME
	
	this->Refresh();
	this->Update();
	
}
Here is the event table used in the main frame:

Code: Select all

wxBEGIN_EVENT_TABLE(cMain, wxFrame)
	EVT_MENU(wxID_INFO, cMain::OnMenuClickedInformation)
	EVT_MENU(wxID_NETWORK, cMain::OnMenuClickedMode)
	EVT_MENU(wxID_CLOSE, cMain::OnMenuClickedExit)
	EVT_COMMAND(wxID_ANY, wxEVT_REMOTE_SET_CURRENT, cMain::OnRemoteSetCurrent)
	EVT_COMMAND(wxID_ANY, wxEVT_DISPLAY_UPDATE, cMain::OnRefreshDisplay)
  	EVT_CLOSE(cMain::OnClose)
wxEND_EVENT_TABLE()
And here are the parameters of the frame constructor:

Code: Select all

cMain::cMain(cEntry* pEntry) : wxFrame(nullptr, wxID_ANY, " ", wxPoint(175, 9), wxSize(850, 1005), (wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER & ~wxMAXIMIZE_BOX & ~wxCLOSE_BOX))
Many thanks,
Ksawery
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Application window refreshing only on mouse movement.

Post by doublemax »

Here is the thread that queues events in the main loop...
Did you leave out the part where the thread actually does something, or is this all it does? (which wouldn't make any sense).

Code: Select all

wxCriticalSectionLocker local_lock(mbMaster->local_guard);
Who else locks this critical section? I wouldn't be surprised if this is the part where the application "hangs" and doesn't refresh its content. This should be easy to find with the logging i suggested in my previous post.
Use the source, Luke!
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Re: Application window refreshing only on mouse movement.

Post by Ksawery »

Did you leave out the part where the thread actually does something, or is this all it does? (which wouldn't make any sense).
The thread only queues events in the main window. Other threads are tasked with fetching or sending new data, which is then shared between all threads in the application. Perhaps this multithreading model is faulty. Should I remove the display-refresh thread entirely, and replace it with a while loop in the main window?
Who else locks this critical section? I wouldn't be surprised if this is the part where the application "hangs" and doesn't refresh its content. This should be easy to find with the logging i suggested in my previous post.
Initially, I also suspected that this might be the case, however, why would it "unlock" only when the mouse is moved? There are several other threads that use the same lock, however, the lock is used for a very short period of time in each case (to fetch a few shared variables and buffers). The other threads are tasked with fetching/sending new data from/to the network and embedded devices.

As suggested, I will need to test the application using logging when I'm in the office tomorrow.

Many thanks,
Ksawery
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Application window refreshing only on mouse movement.

Post by ONEEYEMAN »

Hi,
Because you algorythm is doing so. ;-)
Just get rid of the updating/refreshing thread and do this directly in the main GUI one.

Thank you.
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Re: Application window refreshing only on mouse movement.

Post by Ksawery »

Because you algorythm is doing so. ;-)
Just get rid of the updating/refreshing thread and do this directly in the main GUI one.
Thanks for your reply, however, I don't understand how my algorithm is doing so? How does the process of queuing events from a separate thread cause the main window to only refresh when the mouse is moved? Of course, I now intend to make this change, however, I'd like to understand the actual difference that this change makes.

Many thanks,
Ksawery
Kvaz1r
Super wx Problem Solver
Super wx Problem Solver
Posts: 357
Joined: Tue Jun 07, 2016 1:07 pm

Re: Application window refreshing only on mouse movement.

Post by Kvaz1r »

Ksawery wrote: Tue Dec 29, 2020 5:51 pm How does the process of queuing events from a separate thread cause the main window to only refresh when the mouse is moved?
All UI operations should be done only in main thread. There are no guarantee that updating from other thread will correct.
Mouse moving is event so it unblocks internal event loop from waiting for event.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Application window refreshing only on mouse movement.

Post by doublemax »

The thread only queues events in the main window. Other threads are tasked with fetching or sending new data, which is then shared between all threads in the application. Perhaps this multithreading model is faulty. Should I remove the display-refresh thread entirely, and replace it with a while loop in the main window?
If this thread just has the purpose to send unconditional refresh requests at a fixed rate, a simple timer would have done the same.

How many different elements are there to be updated? Or do you just unconditionally refresh everything?

If the threads are constantly working anyway, you could just have a timer in the main thread, e.g. at 2-20 Hz (which should be enough for gui updates) and update the content from there.

If you want to update specific parts of the GUI depending on which thread produced new data, i would use a wxMessageQueue that's shared among all threads. The worker threads would put a payload into the queue describing which gui parts needs update, the main thread would read from this queue in a timer event and perform the necessary updates.
https://docs.wxwidgets.org/trunk/classw ... _01_4.html

However, all these things will not solve the original issue, there must be another cause for this. Let's wait for the results from your inquiries tomorrow.
Use the source, Luke!
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Re: Application window refreshing only on mouse movement.

Post by Ksawery »

How many different elements are there to be updated? Or do you just unconditionally refresh everything?
I unconditionally refresh everything.
If the threads are constantly working anyway, you could just have a timer in the main thread, e.g. at 2-20 Hz (which should be enough for gui updates) and update the content from there.
I will try using this instead of the worker thread.
2) does the mouse need to be over your application window in order to update the gui, or can it also be outside?
After testing the application today, I noticed that the mouse does need to hover over the window, in order for it to update. The problem also seems to be intermittent. Initially I had the same issue, however after running the project from Eclipse in debug mode, the issue disappeared. Now the issue isn't there, even when I launch the program outside of Eclipse. It's very weird, as I'm finding it hard to reproduce the problem.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Application window refreshing only on mouse movement.

Post by doublemax »

After testing the application today, I noticed that the mouse does need to hover over the window, in order for it to update.
Ok, this is very strange. But it would indicate that the issue is not inside wxWidgets or your application. Moving the mouse outside any of your application windows should not trigger any events and therefore should not have any effect. (Maybe you could confirm that by overriding wxApp::FilterEvent(...) and checking if there are any incoming events in that case).

That sounds more like a Linux theme / window manager issue (Ubuntu is kind of notorious for causing problems with wxWidgets).
Use the source, Luke!
Ksawery
Experienced Solver
Experienced Solver
Posts: 83
Joined: Thu Jul 25, 2019 12:31 pm

Re: Application window refreshing only on mouse movement.

Post by Ksawery »

Moving the mouse outside any of your application windows should not trigger any events and therefore should not have any effect.
Moving the mouse outside the application window doesn't trigger any events, only moving it over the wxWidgets frame. Could that still be related to the Linux environment not working well with wxWidgets? Are there any potential solutions?

I can see that some people are having issues with several wxWidgets programs under Ubuntu 20.04 LTS:

https://askubuntu.com/questions/1276235 ... h-drawings
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Application window refreshing only on mouse movement.

Post by doublemax »

I can see that some people are having issues with several wxWidgets programs under Ubuntu 20.04 LTS:
That issue seems to be a different one, you usually get those kind of artifacts when you move or resize a window (with the mouse).
Are there any potential solutions?
Narrow down the problem even further => create a minimal sample that shows the issue => create a bug report :)

Let's suppose that the content of a wxWidgets app doesn't get refreshed when there is no mouse movement anywhere. In that case it should be reproducible with a simple app that only contains a wxStaticText that is updated from a timer event. Could you test that?
Use the source, Luke!
Post Reply