Opened 14 years ago

Closed 14 years ago

#161 closed defect (fixed)

QWidget and WS_CLIPCHILDREN

Reported by: KO Myung-Hun Owned by:
Priority: major Milestone: Qt Enhanced
Component: QtGui Version: 4.6.2
Severity: high Keywords:
Cc:

Description

Hi/2.

Does QWidget honor WS_CLIPCHILDREN ?

I attached a child window to a QWidget and the window style of QWidget was modified to include WS_CLIPCHILDREN.
Nevertheless, QWidget paints over the child window.

Change History (11)

comment:1 Changed 14 years ago by Dmitry A. Kuminov

We don't use WS_CLIPCHILDREN at all. The explanation is in qwidget_pm.cpp -- though it's mostly true for Qt3 since in Qt4 we don't fully implement non-rectangular child widgets in native mode (this mode means that each child Qt widget is a separate PM window while in Qt4 by default child widgets are "alien" windows that share the HWND with their top-level ancestor and are copmletely controlled by Qt in all aspects including painting, clipping and z-order, so that no special handling for non-rectangular widgets is needed at all).

And I also doubt that changing the WS_CLIPCHILDREN flag on the existing HWND actually affects its behavior (though I never checked that myself).

What are you trying to do? Embed your own HWND as a child of the top-level QWidget? This should work w/o playing with WS_CLIPCHILDREN and if it doesn't then it's a bug that needs to be fixed. And I guess I know why it doesn't work: in alien mode, WM_PAINT is by far not the only place where widget drawing occurs (Qt has its own paint messages) but child widget clipping area detection is done only in WM_PAINT.

I think that in order to fix the problem we need to call qt_WinProcessWindowObstacles() in QRasterWindowSurface::flush() and in QPMDiveWindowSurface::flush() and set the returned region as the clipping region of the target HPS (or exclude it from the area to be updated in DIVE mode).

Could you please provide a simple test case that embeds a child HWND to the top-level QWidget? I will look at it when I've got a bit of time (I'm primarily focused on the different project ATM).

comment:2 in reply to:  1 Changed 14 years ago by KO Myung-Hun

Replying to dmik:

And I also doubt that changing the WS_CLIPCHILDREN flag on the existing HWND actually affects its behavior (though I never checked that myself).

I confirmed. It works.

What are you trying to do? Embed your own HWND as a child of the top-level QWidget? This should work w/o playing with WS_CLIPCHILDREN and if it doesn't then it's a bug that needs to be fixed. And I guess I know why it doesn't work: in alien mode, WM_PAINT is by far not the only place where widget drawing occurs (Qt has its own paint messages) but child widget clipping area detection is done only in WM_PAINT.

Of course, it works without WS_CLIPCHILDREN. But I want to make sure a parent window does not paint over my window. In practice, without this flag, some window overwrites over my window.

I think that in order to fix the problem we need to call qt_WinProcessWindowObstacles() in QRasterWindowSurface::flush() and in QPMDiveWindowSurface::flush() and set the returned region as the clipping region of the target HPS (or exclude it from the area to be updated in DIVE mode).

Good.

Could you please provide a simple test case that embeds a child HWND to the top-level QWidget? I will look at it when I've got a bit of time (I'm primarily focused on the different project ATM).

Ok. You can use SMPlayer.

  1. Launch SMPlayer
  2. Find the hwnd of the movie window of SMPlayer. You can use X-Ray(http://hobbes.nmsu.edu/download/pub/os2/util/wps/xray10.zip)
  3. Launch the updated MPlayer(http://www.ecomstation.co.kr/komh/testcase/mplayer_test.zip) as the following.

mplayer -wid hwnd_id test.avi

where, hwnd_id is hwnd - 0x80000000.

  1. And click the right button of mouse to raise the popup menu.
  2. Clear popup menu
  3. Now movie window is overwritten.

comment:3 Changed 14 years ago by Dmitry A. Kuminov

Okay, I performed the test. Here, it looks like r745 fixed this issue. The only thing what I see is that the movie icon located in the center of the movie window gets overwritten -- but that's probably expected (as well as black flashing background when you activate/deactivate the smplayer window) because of the lack of proper clipping as I described above. I will try to fix it now too.

comment:4 Changed 14 years ago by Dmitry A. Kuminov

In r751, I got the clipping of children working in DIVE mode so that there is no flashing movie window icon/background in the above testcase. Please check how it works for you. Note that there is still one minor redraw problem though which you can see when playing a movie from within SMPlayer (using the same test mplayer executable) -- at the beginning of the playback the movie window gets strangely resized back and forth which causes the main window to resize as well and this leaves a tiny strip right under the movie not redrawn after this resize. This problem goes away if I ignore the vrnDirty flag and reconstruct the visible region at each paint which means that we lack some proper visible region change notification from PM again. I will try to figure that out.

Note that in non-Dive mode, you will still see the flashing background since I didn't apply clipping children to that code path; it will be done later, after I figure out the repaint problem mentioned above.

comment:5 Changed 14 years ago by Dmitry A. Kuminov

I think I found a trick to fix the not repainted strip after the resize. At least, after r753, I don't see it any more.

comment:6 Changed 14 years ago by KO Myung-Hun

I've tested with r753. And it works well with DIVE.

But if I set QT_PM_NO_DIVE=1, the overwritten problem still exists.

comment:7 Changed 14 years ago by Dmitry A. Kuminov

Thank you for testing.

Yes, this is what I wrote in the last paragraph of comment 4. I will apply the fix to this code path when I have more time.

comment:8 Changed 14 years ago by KO Myung-Hun

Ah, ok.

I thought you fixed all the things.

Thanks for your efforts.

comment:9 Changed 14 years ago by Dmitry A. Kuminov

The non-DIVE code path is done in r758. Please try.

comment:10 Changed 14 years ago by KO Myung-Hun

Ok, I've confirmed.

It works fine. Thanks a lot.

comment:11 Changed 14 years ago by Dmitry A. Kuminov

Resolution: fixed
Status: newclosed

You are welcome.

Note: See TracTickets for help on using tickets.