Hello dear Wine developers,
I was using Flash MX under Wine yesterday and I noticed that when I resize the window, the contents swirl around as resize messages get processed. I thought that maybe this could be avoided if the code in wine that processes ConfigureNotify messages from X and passes them on to the windows application could be made to not forward all the messages, but just the ones that mattered. I had a look at the source where this takes place (in dlls/x11drv/winpos.c) and put the following code in the X11DRV_ConfigureNotify function:
XEvent more_events;
. . .
wine_tsx11_lock(); while(XCheckTypedWindowEvent(event->display,event->window, ConfigureNotify,&more_events)) { event=& (more_events.xconfigure); x = event->x, y = event->y; } wine_tsx11_unlock();
So what it does is that when processing ConfigureNotify messages it checks the message queue if there are more ConfigureNotify messages queued up, and only delivers the last one to the windows application.
And actually things ran a bit smoother with this code in place!
Maybe there are potential problems with this code, because it might mean that messages gets delivered in the wrong order, but I have some ideas how this could probably be taken care of. And also some other bits and pieces should be fixed for this to work.
But what do you think about the idea, is it worth exploring further? In that case I could submit a proper patch for this...
-- Mikael
Mikael Lindqvist wrote:
Hello dear Wine developers,
I was using Flash MX under Wine yesterday and I noticed that when I resize the window, the contents swirl around as resize messages get processed. I thought that maybe this could be avoided if the code in wine that processes ConfigureNotify messages from X and passes them on to the windows application could be made to not forward all the messages, but just the ones that mattered. I had a look at the source where this takes place (in dlls/x11drv/winpos.c) and put the following code in the X11DRV_ConfigureNotify function:
XEvent more_events;
. . .
wine_tsx11_lock(); while(XCheckTypedWindowEvent(event->display,event->window, ConfigureNotify,&more_events)) { event=& (more_events.xconfigure); x = event->x, y = event->y; } wine_tsx11_unlock();
So what it does is that when processing ConfigureNotify messages it checks the message queue if there are more ConfigureNotify messages queued up, and only delivers the last one to the windows application.
And actually things ran a bit smoother with this code in place!
Maybe there are potential problems with this code, because it might mean that messages gets delivered in the wrong order, but I have some ideas how this could probably be taken care of. And also some other bits and pieces should be fixed for this to work.
But what do you think about the idea, is it worth exploring further? In that case I could submit a proper patch for this...
I definitely think it is worth exploring further. I'm not sure that the messages could appear in the wrong order, as that would mean that you could never be sure about a window's actual size after resizing it.
On Thu, 2005-12-01 at 16:22 -0600, Robert Shearman wrote:
Mikael Lindqvist wrote:
Hello dear Wine developers,
I was using Flash MX under Wine yesterday and I noticed that when I resize the window, the contents swirl around as resize messages get processed. I thought that maybe this could be avoided if the code in wine that processes ConfigureNotify messages from X and passes them on to the windows application could be made to not forward all the messages, but just the ones that mattered. I had a look at the source where this takes place (in dlls/x11drv/winpos.c) and put the following code in the X11DRV_ConfigureNotify function:
XEvent more_events;
. . .
wine_tsx11_lock(); while(XCheckTypedWindowEvent(event->display,event->window, ConfigureNotify,&more_events)) { event=& (more_events.xconfigure); x = event->x, y = event->y; } wine_tsx11_unlock();
So what it does is that when processing ConfigureNotify messages it checks the message queue if there are more ConfigureNotify messages queued up, and only delivers the last one to the windows application.
And actually things ran a bit smoother with this code in place!
Maybe there are potential problems with this code, because it might mean that messages gets delivered in the wrong order, but I have some ideas how this could probably be taken care of. And also some other bits and pieces should be fixed for this to work.
But what do you think about the idea, is it worth exploring further? In that case I could submit a proper patch for this...
I definitely think it is worth exploring further. I'm not sure that the messages could appear in the wrong order, as that would mean that you could never be sure about a window's actual size after resizing it.
I mean like this, say the message queue looks like this:
ConfigureNotify other message ConfigureNotify
With the "oldest" at the bottom. The code will then search for newer ConfigureNotify messages in the queue, and find it (the one at the top) and deliver that to the application. So it will be delivered before the "other message", whatever that might be, even though the other message happened before.
I don't know in which cases or which kind of messages that could possible end up like this and if it could cause problems. I'm thinking I could use XCheckIfEvent to go through the list and only apply the tactics only if there are several ConfigureNotify in a row, not if there are other messages in between. But I haven't tried this out yet.
-- Mikael
I mean like this, say the message queue looks like this:
ConfigureNotify other message ConfigureNotify
With the "oldest" at the bottom. The code will then search for newer ConfigureNotify messages in the queue, and find it (the one at the top) and deliver that to the application. So it will be delivered before the "other message", whatever that might be, even though the other message happened before.
I don't know in which cases or which kind of messages that could possible end up like this and if it could cause problems. I'm thinking I could use XCheckIfEvent to go through the list and only apply the tactics only if there are several ConfigureNotify in a row, not if there are other messages in between. But I haven't tried this out yet.
I already wrote a patch to fix this problem. It works by getting the actual position of the window on each ConfigureNotify, and throwing it away if the location in the message doesn't match.
Alexandre considers it a hack, and didn't apply it to Wine when I submitted it (quite some time ago).
I've attached the patch; if somebody has the energy to get something like this accepted into Wine, that would be great.
Mike
Index: dlls/x11drv/winpos.c =================================================================== RCS file: /cvstrees/crossover/office/wine/dlls/x11drv/winpos.c,v retrieving revision 1.1.1.48 retrieving revision 1.84 diff -u -r1.1.1.48 -r1.84 --- dlls/x11drv/winpos.c 30 Nov 2005 13:24:09 -0000 1.1.1.48 +++ dlls/x11drv/winpos.c 30 Nov 2005 14:52:06 -0000 1.84 @@ -1184,6 +1431,25 @@ 0, 0, &x, &y, &child ); wine_tsx11_unlock(); } + + /* HACK: find out the real window position... if it doesn't match ignore the ConfigureNotify */ + if (data->toplevel) + { + Window ignore_root; + int ignore_x, ignore_y, height, width, ignore_depth, ignore_border; + + wine_tsx11_lock(); + XGetGeometry(event->display, data->whole_window, &ignore_root, + &ignore_x, &ignore_y, &width, &height, &ignore_border, &ignore_depth); + wine_tsx11_unlock(); + + if ( (width!=event->width) || (height!=event->height ) ) + { + TRACE("Discarding old ConfigureNotify message for hwnd %p\n",hwnd); + return; + } + } + rect.left = x; rect.top = y; rect.right = x + event->width;