Opened 5 years ago

Closed 5 years ago

#80 closed defect (fixed)

Child widgets are sometimes not redrawn

Reported by: dmik Owned by:
Priority: critical Milestone: Qt Beta 4
Component: QtGui Version: 4.5.1 Beta 2
Severity: Keywords:
Cc:

Description

There is one more redraw problem I found. This problem may be seen if a top-level window that contains a combobox is dragged by holding the title bar with the left mouse button while the drop-down list of the combobox is open. The list will disappear after the mouse button press but the appearance of the combobox will remain as if the list is still open (in particular, the list button will remain sunken and the focus will not go back to the line editor).

If, while still holding the mouse button at the title one will move a part of the window containing the combobox partly offscreen and then move it back onscreen, he will see that the part of the combobox that was offscreen will be properly redrawn but not the rest.

Change History (9)

comment:1 Changed 5 years ago by dmik

It looks like we are losing a repaint event somewhere.

Another demonstration of this problem may be redraw defects seen in the smplayer application after pressing Ctrl-C (go to Compact mode) in the main window twice: when the main window switches from Compact mode back to the normal appearance, the menu and the toolbar are not fully redrawn and putting the mouse pointer over them will cause a partial redraw.

comment:2 Changed 5 years ago by diver

  • Milestone changed from Qt GA to Qt Beta4
  • Priority changed from blocker to critical

comment:3 Changed 5 years ago by dmik

One of the symptoms is that focus in and focus out events (e.g. activating and then deactivating the window) don't cause child widget updates while focus events themselves are delivered well. Interesting that sending *any* PM message in the target window after that will cause paintEvent() to be activated which properly updates the child widget's look -- it's enough to move the mouse over the window's frame (which sends WM_HITTEST to WC_FRAME) to cause this to happen.

My bet is that the code processing window activation/deactivation and sending focus events also posts a repaint event but that event is for some reason stuck in the Qt event queue until the next native message wakes it up.

comment:4 Changed 5 years ago by dmik

Okay, the suspicion was right. QCoreApplication::postEvent() places an event to the Qt event queue and wakes up the real native event queue by calling QEventDispatcher::wakeUp() which due to a bug did nothing on OS/2. Fixed in r302. This fixes the focus traversal & redraw problems but doesn't fix the original repaint issue. Searching further.

comment:5 Changed 5 years ago by dmik

I've got a feeling that repainting problems occur due to popups (this includes #91 as well) -- in both cases popups are shown. By design, popups consume almost all events when they appear on screen. I think that on OS/2 they somehow also consume repaint events designated to other widgets.

comment:6 Changed 5 years ago by dmik

I found the root of all repaint problems. Basically, it's in sendUpdateRequest() (qbackingstore.cpp). In more detail, the thing is that Qt uses a heavily customized repaint scheme that doesn't always involve native WM_PAINT events and window update regions. However, in some cases these custom updates do not actually draw anything on screen (most likely, either the HPS they get is invalid or there is a mixup in coordinate space shifting/flipping). If I change sendUpdateRequest() to always update the whole top-level window (which is of course slow) then all repainting problems I know of (including #91) disappear.

I will find out whats wrong with the custom path tomorrow.

comment:7 Changed 5 years ago by dmik

Fixed a couple of redraw bugs in QPushButton (r305, r306). Despite that change sets are really tiny, finding these bugs requires a lot of debugging...

comment:8 Changed 5 years ago by dmik

For some reason, the presentation space for the widget that we get in QRasterWindowSurface::flush() through WinGetPS() is partly clipped and that's why some parts are not redrawn. I need to find who clips it out and why.

comment:9 Changed 5 years ago by dmik

  • Resolution set to fixed
  • Status changed from new to closed

Okay, it was a tiny bug too. Fixed in r307. This seems to fix a lot of repaint problems, including combo-boxes and Ctrl-C in smplayer mentioned above as well as #91 and many painting problems one could see in the textedit demo program (such as selecting all text and changing its size does only update what was behind the popup list of the combo-box with font sizes, etc.).

The matter is that Qt updates sometimes can intersect with native WM_PAINT events. Due to the bug, the Qt-maintained dirty region was not actually added to the system-maintained update region but was cleared in WM_PAINT (to avoid further update requests). As a consequence, the native clip region didn't include all dirty areas (this is what I saw when looking at the clip box of the presentation space in QRasterWindowSurface::flush()) and they were left unpainted. This was always the case when another top-level window was moving above the given Qt top-level window.

Enough for this ticket.

Note: See TracTickets for help on using tickets.