Problems with GUI refresh on macOS

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.
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Problems with GUI refresh on macOS

Post by TobaYn3 »

Hey, I'm having trouble to port my application to macOS Sierra and would be grateful for any help.
It is a network capturing tool for a specific protocol (similar to Wireshark), which successfully runs on Windows and Linux so far.
I managed to get it compiled with gcc and am able to start it, but parts of the GUI freeze after startup and I don't know what might be the problem.

Some background:
The main window consists of a splitter window containing two more splitter windows, so you have four individually resizable tiles.
Each wxPanel in the four tiles can be detached from the window and will then be integrated in a seperate wxFrame. The program is started with all tiles in the main frame. At startup, several threads, which are using the PCAP library to capture and analyze network traffic, are started. These threads generate events on network packet reception. The events are being processed by the tiles (wxPanel) and are also forwarded to the main window. In my test network, this may lead to about 100 events being generated per second. Therefore, I added a mechanism to my GUI, that GUI updates shall not be made more often than every 200ms. As said in the introduction, the GUI is not updated after startup, instead most parts simply stay black. On tile contains a wxDataViewCtrl. This is the only control which is shown correctly and also updated, which is why I don't think it is a generous problem, but only a problem of updating the GUI.

Does anyone have an idea how to fix this?

Thanks in advance for any hint!

Appendix: If I detach one of the wxPanels from the main window, everything within the seperate window is shown correctly and refreshed as desired.
wxWidgets version 3.0.3, macOS Sierra (10.12), gcc version 4.2.1
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

It's hard to give specific advice, first you have to isolate the problem. E.g. disable the threads and let the custom panels just draw any content that changes over time. If that works, you know that the drawing code is ok. Then enable the threads again and try to reduce the amount of events they sent. Maybe the event loop is just saturated.
I added a mechanism to my GUI, that GUI updates shall not be made more often than every 200ms.
How exactly did you do that? If you only need an update 5 times per second, i would not send events from the worker threads. Instead i would just have them store the data in a shared buffer and have a timer that fires 5 times and second that just updates the data and refreshes the panels.
Use the source, Luke!
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

Thanks a lot for your ideas!

I will give the wxTimer thing a try tomorrow. I'm using a shared list, anyway. Should have come up with that idea by myself. #-o

I did make the experience, that using wxTimers produce a lot of flicker on Windows, although I'm using double buffering, already. Is that true or just a wrong impression?

If that doesn't do the trick, I will try to disable the threads and see what happens.

To prevent the GUI from being updated, I simply take a timestamp (wxDateTime::UNow) when an event is being processed and compare (wxTimespan) it to the last update time. Maybe too much timestamping for macOS?
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

I did make the experience, that using wxTimers produce a lot of flicker on Windows, although I'm using double buffering, already. Is that true or just a wrong impression?
The use of timers can't have anything to do with flickering. I all depends on the drawing code.
To prevent the GUI from being updated, I simply take a timestamp (wxDateTime::UNow) when an event is being processed and compare (wxTimespan) it to the last update time.
So basically you would only send an event 5 times per second? Then it should be about the same as the timer approach.
Use the source, Luke!
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

No, I'm not sending the event only 5 times per second. I'm taking the timestamp in the event handler function.
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

I removed all the events and implemented a timer. Still the black GUI on macOS.
Anyway, good hint. This will be a performance improvement on Windows and Linux.

I also tried to disable the threads running in the background. No change.
The dataview control is the only control which is shown and refreshed, correctly.
As soon as I detach one of the other panels from the main window, everything within the seperate window works fine.
Does this somehow have to do with the wxSplitterWindow?
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

Does this somehow have to do with the wxSplitterWindow?
It shouldn't be. Especially can't i think of any reason why this should happen only under OSX.

Do the panels have the wxSplitterWindow as parent?

How are the paint event handlers for the panels connected? Can you show some code?
Use the source, Luke!
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

I just found out, that the GUI is updated each time I drag the sash of one of the splitter windows.
What I did now is I added a SendSizeEvent() call to the end of the timer event function and now the GUI is being drawn and refreshed correctly.
Of course, this can't be the solution. The question is why does macOS not automatically redraw the window, if I replace the SendSizeEvent() call with Update() or Refresh() the window stays black.

Yes, as long as they are embedded into the main window, the splitter window is their parent. I don't know what you mean with the paint event handlers. I did not implement them by myself, I am using standard wxPanel.

Edit: Calling SendSizeEvent() every 100ms seems to lead to ~100% CPU utilization by my application in the macOS resource monitor.
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

if I replace the SendSizeEvent() call with Update() or Refresh() the window stays black.
For which object are you calling Refresh()?
I don't know what you mean with the paint event handlers. I did not implement them by myself, I am using standard wxPanel.
Ok, that makes it even stranger. When something goes wrong with redraw, i naturally assumed it's a custom drawn window.

Can you try to build a minimal sample with just a splitter window and two panels and check if you see the same problem?
Use the source, Luke!
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

To clarify: I added a 100ms wxTimer to the frame and do all the refreshing of the subpanels within the timer function. At the end of the function, I call SendSizeEvent() for the frame instance and everything is displayed correctly. If I replace SendSizeEvent() by Refresh() or Update() - also of the frame instance - black screen.

I will give the minimal example a try, but I doubt that I will see the same behaviour.
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

FYI: I have a satisfying workaround for this.

I wanted to find out the reason why the SendSizeEvent() call fixes the problem.
Therefore, I commented out the complete content of the frames OnSize() function and started to comment more and more parts in.
I noticed, that the problem was related to the tile at the bottom left, which is the only one that contains another splitter (mainSplitter -> leftSplitter -> leftBottomPanel -> leftBottomSplitter). By any reason, this panel seems to need a frequent Layout() call. I replaced SendSizeEvent() in the timer function by leftBottomPanel->Layout() and leftBottomPanel->Refresh() and everything works fine. I'll leave it at that for now, although I have no idea what might be the reason for this.

Thanks for your help!
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

I commented out the complete content of the frames OnSize() function
Whatfor do you need the OnSize handler anyway? Do you call event.Skip() inside?
Use the source, Luke!
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

doublemax wrote:Whatfor do you need the OnSize handler anyway? Do you call event.Skip() inside?
I need it because I change the font and button size according to the window size. Yes, I do call event.Skip() at the end of the function.
TobaYn3
Earned a small fee
Earned a small fee
Posts: 11
Joined: Thu Aug 17, 2017 1:49 pm

Re: Problems with GUI refresh on macOS

Post by TobaYn3 »

I now see another problem with the same GUI on Macs with a 4K display. The screen stays black and also won't show up when resizing.
When running the application as root, everything is fine.

I saw in the changelog for wxWidgets 3.1.0 that there have been several improvements for high DPI screens.
Unfortunately, when compiling the application with wxWidgets 3.1.0, I get my old problems back.
The GUI won't show up, event not on non-4K displays, although I call Refresh() and Layout() for the left bottom panel.

This is weird...
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Problems with GUI refresh on macOS

Post by doublemax »

Maybe you're doing something wrong, but without seeing code or - even better - a minimal, compilable sample that shows the problem, it will be hard to track the problem down.
Use the source, Luke!
Post Reply