UI regression

Duane Clark junkmail at junkmail.com
Sat Mar 2 10:45:35 CST 2002


Jon Piesing wrote:
> Hi,
> 
> Earlier this year I "upgraded" from wine 20010510 to 20011226 in order
> to see if some kind of resource leak was fixed which caused screen 
> redraws to get progressively slower and slower and slower and slower, ....
> 
> That was fixed but there seemed to be a significant number of graphics
> and UI regressions. I've just upgraded to 20020228 to see if things
> were any better and within 5 minutes I've hit one of the ones I saw before.
> 
> In this case, screen re-draw works except for scroll-bars which are not
> drawn at all. If I look at the xterm where I start wine, I just see the
> same error message being printed over & over again ...
> 
> err:msg:DispatchMessageA BeginPaint not called on WM_PAINT for hwnd 2002e!

By the way, I doubt the patch I posted will fix this. I have two apps 
with misbehaving scrollbars, and the earlier patch only fixes one of 
them (and I have my doubts whether it is the right fix - more testing 
later). It has the behavior that when when the window layout changes, 
the scrollbars don't get drawn. So it is not really a refresh problem.

The second app that I have has a refresh problem. When I obscure part of 
the window with the scrollbars (it is a sub-window within the app) but 
don't obscure any of the scrollbars, and then unobscure it, the window 
is completely repainted but not the scrollbars. If any part of the 
scrollbars were obscured, then the window and scrollbars both get 
repainted.

And anything that does the obscuring triggers this behavior. It can be 
another window brought in front, or conveniently, a dropped down menu. 
For example, I drop down a menu, then slide the mouse left to the next 
menu, and when the menus switch, the window is repainted. And the 
scrollbars are only repainted if the menu was covering a portion of the 
scrollbars.

Does this sound something like what you are seeing? If it is, then the 
trick to debugging is to get an event that is easy to find in a trace, 
rather than searching through MBs of traces. And in my case, the easy 
item to find is the menu switching.

So if you are interested, here is what I have done so far. I like to 
write this down anyway, since it gives me a chance to sit back and kind 
of try to get the big picture.

First I ran my app without logging and minimal messages.
  wine --debugmsg +scroll fpga_editor.exe
This shows me
  trace:scroll:X11DRV_ScrollWindowEx 10045, 0,-5
  trace:scroll:SCROLL_HandleScrollEvent Event: hwnd=10049 bar=2
So my main window is hwnd (window handle) 10045 and the vertical 
scrollbar is 10049.

Next I run it and log a bunch of messages.
  wine --debugmsg +scroll,+menu,+win fpga_editor.exe >& fpga.log

I go through the menu drop down and switching process, and then go to 
the log. One of the subitems in the drop down menu has the word 
"Arrange" so I search for that. The first occurrences are early, 
obviously initial creation, so I scroll to the middle of the log file 
and search from there. It takes me right to the area, and scrolling just 
slightly further, I find this:

trace:menu:MENU_SelectItem owner=0x10021 menu=0x00a0 index=0x0003 
select=0x0001
trace:menu:do_debug_print_menuitem MENU_DrawMenuItem:  { ID=0x334, 
Sub=0x334, Typ=pop, Text=L"&Window" }
trace:menu:MENU_DrawMenuItem rect={188,24,255,42}
trace:win:FillRect TRACEME hdc 74
trace:menu:do_debug_print_menuitem MENU_DrawMenuItem:  { ID=0x1cc, 
Sub=0x1cc, Typ=pop, State=hi, Text=L"&Tools" }
trace:menu:MENU_DrawMenuItem rect={136,24,188,42}

This is my menu switch, from the "Window" menu to the "Tool" menu. Good, 
this is the right area. Now I start looking for references to my window, 
hwnd 10045. A little further down, the first references are in a bunch 
of areas that look like this:

trace:win:RedrawWindow 10021 (15f6) rect 184,58-375,99 0000 flags=0085
...
trace:win:RDW_UpdateRgns hwnd 10045 [0000] -> hrgn [15fa], flags [0485]
...
trace:win:RDW_Paint 	hwnd 10045 [1632] -> hrgn [15fa], flags [0085]

These are creating update regions (I think) but not actually redrawing 
the areas that had been obscured by the "Windows" menu. I know this 
because I have a "ruler" I made with marks every 50 pixels, and I can 
see that when the "windows" menu is dropped down, it extands from 
approximately 18x-37x in the horizontal direction. Which corresponds to 
the rectangle above, rect 184,58-375,99. It is creating update regions 
one menu label at a time.

Going past this, the next reference to 10045 is:

trace:win:RedrawWindow 10045 (1626) NULL 0,0-0,0 0000 flags=0050
trace:win:RDW_UpdateRgns 	hwnd 10045 [1626] -> hrgn [0000], flags [0050]
trace:win:RDW_Paint 	hwnd 10045 [1626] -> hrgn [0000], flags [0050]
trace:win:RedrawWindow 10045 (1626) NULL 0,0-0,0 0000 flags=0050
trace:win:RDW_UpdateRgns 	hwnd 10045 [1626] -> hrgn [0000], flags [0050]
trace:win:RDW_Paint 	hwnd 10045 [1626] -> hrgn [0000], flags [0050]
trace:win:BeginPaint TRACEME hwnd 10045
trace:win:begin_ncpaint hwnd 10045 [1626] ncf 4
trace:win:BeginPaint hdc = 74 box = (0,0 - 749,661)

This is interesting. Looking at the function RedrawWindow:

http://www.winehq.com/source/windows/painting.c#L663

the call has been made with both hrgnUpdate and rectUpdate (the 
lprcUpdate parameter) as NULL. According to the MS docs (one long line):

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/win32/funclist_01kj.asp

"If both the hrgnUpdate and lprcUpdate parameters are NULL, the entire 
client area is added to the update region."

And indeed, soon after there is the line that says BeginPaint on the 
rectangle (0,0 - 749,661), which using my handy ruler, I can see is 
indeed the entire scrolled window. But nowhere does the scrollbar, 
window 10049, get repainted.

Another interesting thing I see above is that the flags are "0050". 
Looking at the RedrawWindow function, I see that the flags are RDW_*, so 
I go to the include directory and "grep RDA_ *", and find that:
winuser.h:#define RDW_NOINTERNALPAINT  0x0010
winuser.h:#define RDW_NOCHILDREN       0x0040

So there is a "NOCHILDREN" flag. A tried deliberately changing this to 
"ALLCHILDREN" whenever both the hrgnUpdate and lprcUpdate parameters are 
NULL, on the theory that you always want to repaint the children if the 
entire window is being repainted. That changed the flags, but the 
scrollbars still were not repainted.

So that is where I am now, still looking. I am kind of new to this, so I 
am still learning my way around wine.

-- 
My real email is akamail.com at dclark (or something like that).




More information about the wine-users mailing list