bugGNU Octave - Bugs: bug #44776, [Qt] Restore window button does...


bug #44776: [Qt] Restore window button does not trigger a repaint event for its content

Submitter:  Lutz Mager <rocketsound>
Submitted:  Wed 08 Apr 2015 03:26:53 PM UTC
Category:  Plotting with OpenGL Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * 4.2.1 Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup

Jump to the original submission

Thu 28 Feb 2019 09:13:04 AM UTC, comment #29: 

@Mario: This is already tracked in bug #53709 for uipanel objects which are another flavor of Qt widgets. Can you add a comment there stating that uicontrol objects are also affected?

Pantxo Diribarne <pantxo>
Group Member
Thu 28 Feb 2019 09:03:25 AM UTC, comment #28: 

In octave 5.1.0 the window maximize/restore button updates the axes size, however the position of uicontrols are still not updated. Tested with the demo_uicontrol.m from the wiki.

Mario Mielenhausen <mariomie>
Thu 01 Nov 2018 03:32:17 PM UTC, comment #27: 

On the dev branch this now works correctly.  It's still messed up in 4.4.1, but given that 5.0 should be released in another two months I don't think that is a problem.

Marking as fixed and closing report.

Rik <rik5>
Group administrator
Thu 01 Nov 2018 12:38:37 PM UTC, comment #26: 

I backed out cset b57b7f3f5e61 which solves this bug and does not trigger the issue it was supposed to solve. Marking "Ready for test".

Pantxo Diribarne <pantxo>
Group Member
Tue 11 Apr 2017 06:10:27 PM UTC, comment #25: 

Please post the same information and question over on bug #44330; There may be users who are following that bug rather than this one.

Rik <rik5>
Group administrator
Tue 11 Apr 2017 06:02:22 PM UTC, comment #24: 

I tried to backout the changeset that prevents the figure from being correctly redrawn after resizing (http://hg.savannah.gnu.org/hgweb/octave/rev/b57b7f3f5e61?revcount=120) and

  • indeed it solves this bug for me
  • I can't reproduce the segfault it was supposed to resolve (see bug #44330). I tried the following

h = figure (); close (h);h = figure (); close (h);  h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h); h = figure (); close (h);

Any objection against this backout?

Pantxo Diribarne <pantxo>
Group Member
Sat 20 Aug 2016 11:39:48 AM UTC, comment #23: 

So I've found that there's a difference in behaviour with ./run-octave --no-gui and ./run-octave on QT5. I can't quite reproduce your problem but using the gui interface on QT5 for me means I do get the black screen (amongst other bugs which I guess I need to report.)

I wonder if the issue you're facing is something to do with the opengl_renderer in gl-render.cc - I wouldn't be surprised if there was something in there that nvidia driver was barfing on. I am certain there are some bugs in there - for example if you take a window and resize it down to the smallest it can be and then, resize it up you'll get a complete mess.

Now, as I can't reproduce your problem I guess we need to think about how to debug it on yours...

I'd take a look at gl-render.cc - you could start with adding qDebug () or std::cout statements to each of the draw functions to see if they appear to be being double called or chase them back up the call-stack.

I think it might be also worth looking at and wiring in: http://doc.qt.io/qt-5/qopengldebuglogger.html#details

Fri 19 Aug 2016 09:04:20 PM UTC, comment #22: 

I'm running Nvidia driver on Cinnamon 2.8.1 (and various combinations of Cinnamon utilities in the vicinity of 2.8.1).

Here's the interesting thing.  I do

>> graphics_toolkit ('qt')
>> figure
>> sombrero

Half the time I end up with a grey screen with a white box in the upper left corner and the pager is stuck.  I've reported that bug elsewhere.  However, if the figure window appears with a proper display the sombrero appears.

Now, here's something new and interesting (pre-patch).  The first time that I grab the lower right corner and drag, the figure replots normally.  No black screen flashing, and the surface looks complete.  However, if I release the mouse and let go of the window corner then repeat this process, now the black background appears and I can see that the surface doesn't fully draw.  Instead it randomly draws somewhere in the vicinity of half the surface before doing another redraw.

Apparently there is some type of state variable inherent in this redraw (Octave or Qt) that maybe isn't being set to a proper value upon releasing the mouse.  It is probably something to do with blocking the redraw until the previous redraw is complete...  Wait!  Here's another little detail.  I was curious if maybe the problem is that I let go of the window corner in the middle of a redraw.  That appear to be the source of the problem.  If I drag the corner around, stop and wait until I'm certain the sombrero redraw is complete, then let go of the mouse button there appears to be no black screen when I repeat this little test.

Some state variable is being reset on account of a button release (or possibly more types of) events when the renderer is drawing when maybe those events should be blocked or discarded when the renderer is active.  I think it is a good guess that this is also the source of my randomly grey screen when running a simple "figure()".

Anyway, I'd say your patch is fine, but really this Qt plotting should be made robust as a main priority.  Folks have tried solving these kinds of bugs with things like fraction-of-a-second delays and so on.  That's just sweeping the dust under a rug.

Dan Sebald <sebald>
Fri 19 Aug 2016 08:13:40 PM UTC, comment #21: 

Interestingly I can't seem to get the black background issue to happen anymore on the latest changeset: 22343:029c5f4eac3a - neither on qt4 nor qt5. Dan - what are you running?


PS I'm also on linux with intel driver on cinnamon 3.07.

Fri 19 Aug 2016 03:19:52 PM UTC, comment #20: 

I've switched over to Qt5 now.

I used Meld to look more closely at the changes.  I didn't follow through the code to see what

fp.set_boundingbox (bb, true, false);

does, but generally speaking the patch does seem to add a piece that seems missing, i.e., reaction to the Resize event.  Makes sense to me.

I was just pointing out that the now-sluggish multiple drawing with each plot might be covering up the behavior I was originally seeing with this bug report, so I can't confirm the patch does anything.  No objections to applying the patch though.

Maybe someone committed a changeset to address this issue but in a clumsy fashion.  Rik, should we locate where this plot double-draw was introduced sooner rather than later?

Dan Sebald <sebald>
Fri 19 Aug 2016 06:54:05 AM UTC, comment #19: 

Is this the black background problem in qt5 or qt4? In qt5 I'm seeing a black background an awful lot with or without this patch.

I will take a look at what's causing the black background, but without this patch you cannot maximize an octave UI window on any platform and expect any component to be correct.

Fri 19 Aug 2016 03:54:29 AM UTC, comment #18: 

I've applied this patch and will note behavior before and after. 

The problem is that Qt plotting now (before applying patch) seems to have some redundancy that was introduced along the way recently.  Someone probably solved an issue which consequently draws more than once for each plot.  So, that may have solved the issue here (or at least the way I described it), or more like maybe covered up the original issue.

After applying patch https://savannah.gnu.org/bugs/download.php?file_id=38259 the only thing that stands out is that the background is more likely to turn from white to black while dragging a corner of the window to resize the plot.  It is especially likely if the window corner is dragged slowly.  Attached is a screen shot.

Without the patch I do see the black background once in a while, but it occurs at a much slower rate.

I'd say that from my perspective, given the state of Qt plotting, it might be best to lower the priority on this one.  If it solves something on Windows, go ahead and apply the patch.

Dan Sebald <sebald>
Thu 18 Aug 2016 08:22:20 PM UTC, comment #17: 

So there doesn't appear to be any bad effects on SizeChangedFcn.

I think therefore the bug fix solves the issue.

Thu 18 Aug 2016 07:05:33 PM UTC, comment #16: 

OK I think I have a fix for this completely now.

Basically, before the Figure's Container gets the QEvent::Resize we resize the main window. I have then removed the unnecessary two other resizes from the after event filter.

Further in updateBoundingBox the use of gh_manager::post_function updateBoundingBoxHelper meant that the updates to the figure's main window size were occuring after other elements were informed so I have now made this updated.

What are the possible problems with this approach?

  • I think we need to ensure that the ResizeFcns are not adversely affected by this. The immediate post_set could lead to slow updates when resizing figures. I have not completely tested this yet.

(file #38259)

Mon 15 Aug 2016 09:34:36 PM UTC, comment #15: 

Actually it turns out that in comment #14 I was completely wrong.

The QEvent::Resize / resizeEvent does actually reach the figure. The problem appears to be that the children of the figure get asked to update themselves before the figures properties are updated.

Basically it appears that the resize of the child objects occurs before the resize to the figure itself. Leading them to be updating their size on the wrong number.

I've attached a (hacky) partial bug fix for this. In order to check the difference look at scrolling and maximizing this:

uicontrol('Style', 'text', 'String', 'TEXT', 'Units', 'normalized', 'Position', [0 0 1 1])

This doesn't fix the sombrero issue however.

My fix works by forcing an update to the figure properties before passing the update down to the container. Further, by forcing the update rather than passing a function this ensures that it happens before the child objects.

I suspect that this might not be the correct thing to do but hopefully it will show the way to properly fix this.

(file #38225)

Sun 07 Aug 2016 03:56:53 AM UTC, comment #14: 

Hi! I've just noticed this bug too.

The main issue is that the QEvent::Resize / QResizeEvents are not emitted by qt for window restore - rather you need to listen for a QEvent::WindowStateChange / QWindowStateChangeEvent, then look at the difference between the QWindowStateChangeEvent.oldState() and  QWidget.windowState().

This could probably be done in Figure.cc and then a fake QEvent::Resize could be emitted to pass the event down to all the children.

On the other issue of fast-dragging updates (first mentioned in comment #2) I agree with Dan Sebald's comment #10. I suspect that the problem is one of simultaneous read/write of window size and/or reordering of events between the octave and QT threads. Regarding failure to resize in busy octave threads - this can be a problem in matlab too.

Tue 02 Jun 2015 04:41:34 PM UTC, comment #13: 

Retagging release from 4.0.0-rc2 to 4.0.0.

John W. Eaton <jwe>
Group administrator
Fri 10 Apr 2015 06:23:41 PM UTC, comment #12: 

No thanks.

Dan Sebald <sebald>
Fri 10 Apr 2015 06:16:38 PM UTC, comment #11: 

Given that a figure can contain a menubar and toolbars, it would be difficult to inherit from QCanvas or QGraphicsScene. Or you'd need another outer container. But the fact is that a Matlab figure has a dual personality: it represents the external window (with a toolbar, a menubar...), and at the same time it represents the internal container (QMainWindow's central widget; e.g. "position" property maps to the position of the central widget in global coordinates; removing the figure's menubar doesn't change the "position" property, which means you have to move the outer container to keep "position" constant...). This dual personality makes things more complicated than it seems.

That being said, you are obviously welcome to rewrite the graphics code using a state-of-the-art approach.

Michael Goffioul <goffioul>
Fri 10 Apr 2015 05:57:13 PM UTC, comment #10: 

I didn't look that closely at the code, but I looked close enough to get a feel for things.  I've seen these sorts of window size and update issues a lot with gnuplot development, for example, where there is the core routine and an outboard driver through a pipe.  It can get sort of tangled, adding variables here, conditional there.  Things like static methods or whatnot often seem to complicate matters rather than add benefit.

I tend to take a broader view regarding the overall communication and flow across threads.  As I see it, somewhere in the mix needs to be a Mutex to prevent a clash of simultaneous data modification and/or redraw timing.  A C callback on its own simply doesn't have that.

Personally, for elegance I would have attempted to derived Figure from, what is it, QCanvas, QGraphicsScene?  Some Qt object that already has the window modification and redraw signals as part of it.  There probably already is a signal in those types of Qt objects emitted when the window is resized.  The responding slot would either send a command to Octave core with the new size (the command interface, by construction, has a Mutex), or the window size would be copied to some shared memory with Octave core, which should have a Mutex.

There's also the question of Octave core rendering while it is processing.  It's not that important to me, but I'm sure there will be users saying "can't change the figure size while a long processing job is running".  (In fact, I think there is a related bug I've just noticed in attempting to resize when octave is processing.  Changing the window size results in the figure not being redrawn at all once the interpreter finishes processing.)  It might make sense to have Octave gl-renderer be an independent hunk of code so that resizing can be done when Octave is processing.  Also, not the easiest thing.

As I say, it's just a gut feeling that the sort of pieces to make plotting work smoothly aren't there.  Probably have to settle for with some quirky operation for the time being.

Dan Sebald <sebald>
Fri 10 Apr 2015 12:29:46 AM UTC, comment #9: 

The condition on the signal is because the method Figure::updateBoundingBoxHelper is used for 2 different purpose, though very similar: updating the outer and inner bounding box of the figure object. In only one case, we want(ed) to force a figure redraw, but only after the execution figure::properties::set_boundingbox, as the latter can have a bunch of side-effects (e.g. execution of resizefcn callback) that you need to take into account. I could have used 2 different functions, updateInnerBoundingBoxHelper and updateOuterBoundingBoxHelper, but this didn't seem worth it, as most of the would have been identical, except for emitting the signal.

Also maybe you didn't realize, but Figure::updateBoundingBoxHelper is static, so there is no "this" context and you can't simply do "emit asyncUpdate()". The code doesn't emit a signal for another object, the figure object delegates the emit of its own signal to one of its static method, because the signal will have to be emitted from the octave thread, by queueing the static method with gh_manager::post_function. This is basically an alternative to queueing a bound-method. Using C++11 lambda expression would probably make the code more elegant.

There is a gh_manager::post_set method to queue property changes, but this use case was different ("boundingbox" is not a figure property).

Michael Goffioul <goffioul>
Thu 09 Apr 2015 04:36:05 AM UTC, comment #8: 

Ah, this is another of the callback sort of constructs.  That crashes because the GUI can delete the figure object asynchronously and the callback uses the pointer in a way it shouldn't.

Getting the bounding box change back to Octave figure properties is one of those things that could be accomplished with sending the core a "set()" command, if such a thing existed.  Or something similar that uses a Mutex.

Not sure this issue can be fixed too easily.

Dan Sebald <sebald>
Thu 09 Apr 2015 02:15:29 AM UTC, comment #7: 

The long shot fixes the problem.  Well, sort of.  It ends up doing a double draw most of the time which doesn't look so nice - similar to what's under discussion here:


Couple comments about this construct:

      if (d->m_internal)
        emit d->m_figure->asyncUpdate ();

Emitting a signal usually doesn't need a conditional.  Instead, making a connection or not making a connection accomplishes the same thing.  That is, emit mySignal () won't do anything if there is nothing connected to it.  Also, although technically nothing is wrong with emitting a signal belonging to another object and I've not read anything that discourages it, my thought is why not make the signal part of the object, i.e., Figure:asynchUpdate()?  The advantage is not having additional variables to keep track of externals.

Dan Sebald <sebald>
Thu 09 Apr 2015 01:31:21 AM UTC, comment #6: 

Probably a long shot, but any chance this has been affected by this change:


Michael Goffioul <goffioul>
Wed 08 Apr 2015 10:47:26 PM UTC, comment #5: 

Since Rik changed the title: For me (with Windows 7) also maximizing doesn't trigger the repaint event (see the screenshot). This also includes maximizing via double clicking the window borders.

Lutz Mager <rocketsound>
Wed 08 Apr 2015 06:23:59 PM UTC, comment #4: 

Confirmed on a Linux machine so this is not specific to an OS.

Sample steps to reproduce:

graphics_toolkit qt
# Click on Maximize button of figure window
# Figure will expand to fill screen, and contents will be autoscaled.

# Click on Restore (Maximize again) button of figure window
# Figure will shrink to original size, contents will be cut off

# Click in Canvas to cause update of contents

Rik <rik5>
Group administrator
Wed 08 Apr 2015 05:30:35 PM UTC, comment #3: 

It's hard to tell, but it seems the figure may be redrawing but with the incorrect size window size.  The first time I tried maximizing the figure size was correct.  But I then minimized and the figure was still appeared too big as in your example screenshot.  Maximizing then made a figure that was too small.

It's as if the redraw is using the one-previous window size and randomly sometimes the current window size.  This behavior would not be noticeable when dragging the window size slowly because if the window size is off one or two pixel there's not much difference in size.  Comment #2 suggests the same thing: fast-drag is more noticeable.

There could be a race condition between the drawing of the figure and the update of the window size.

Dan Sebald <sebald>
Wed 08 Apr 2015 04:06:19 PM UTC, comment #2: 

I observe the same thing on Linux when you maximize/restore a window or when dragging back a window from the screen edge (snap sizing). It also happen if you resize quickly a window using the window borders (especially when reducing its size).

Guillaume <gyom>
Wed 08 Apr 2015 03:29:25 PM UTC, comment #1: 

Notice the screenshot. It shows a figure after maximizing and restoring its window.

Lutz Mager <rocketsound>
Wed 08 Apr 2015 03:26:53 PM UTC, original submission:  

If you resize a figure window via its borders the content (like plots, ...) also will be resized and repainted accordingly to the available space. But this does not work if you maximize/restore the window or double click the windows borders (this will resize the window in a way such that it uses the whole vertical or horizontal space of your screen, I don't know if this feature is also available on Linux desktops).

Any event inside the figure window will trigger a resizing/repaintng of the plots but it would be better if the figure immediatley resizes/repaints its content after maximizing/restoring the window.

Only tested on Windows 7.

Lutz Mager <rocketsound>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Attached Files
file #38259:  bug-44716-fix-20160818.diff added by None (3KiB - text/x-patch)
file #38225:  bug-44716-partial-fix-20160815.diff added by None (2KiB - text/x-patch)
file #33607:  Screenshot 2.png added by rocketsound (49KiB - image/png)
file #33596:  Screenshot.png added by rocketsound (13KiB - image/png)


Depends on the following items: None found

   bug dependencies.


Carbon-Copy List
  • -email is unavailable- added by mariomie (Posted a comment)
  • -email is unavailable- added by mayeulc (I'll follow this instead of duplicate 53475)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by rocketsound (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.


    Follow 16 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-11-05 mayeulc Carbon-Copy- Added mayeulc
    2018-11-01 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2018-11-01 pantxo CategoryPlotting Plotting with OpenGL
    2018-11-01 pantxo StatusConfirmed Ready For Test
    2017-04-24 pantxo Dependencies- bugs #50864 is dependent
    2017-04-11 pantxo Release4.0.0 4.2.1
    2016-08-19 sebald Attached File- Added Screenshot_black_background_while_resizing.png, #38268
    2016-08-18 None Attached File- Added bug-44716-fix-20160818.diff, #38259
    2016-08-15 None Attached File- Added bug-44716-partial-fix-20160815.diff, #38225
    2015-06-02 jwe Release4.0.0-rc2 4.0.0
    2015-04-08 rocketsound Attached File- Added Screenshot 2.png, #33607
    2015-04-08 rik5 StatusNone Confirmed
        Operating SystemMicrosoft Windows Any
        Summary[Qt] Maximizing a figure does not trigger a repaint event for its content [Qt] Restore window button does not trigger a repaint event for its content
    2015-04-08 rocketsound Attached File- Added Screenshot.png, #33596

    Back to the top

    Powered by Savane 3.13-4b48.
    Corresponding source code