Made sure ConfigureNotify is processed before Expose, deferring the
Expose event if necessary, thus working around a WM flaw with virtual desktop scrolling in -managed mode.
This commit is contained in:
parent
3b7212809b
commit
0fbe1de1f7
|
@ -83,6 +83,7 @@ typedef struct tagWND
|
||||||
HMENU16 hSysMenu; /* window's copy of System Menu */
|
HMENU16 hSysMenu; /* window's copy of System Menu */
|
||||||
DWORD userdata; /* User private data */
|
DWORD userdata; /* User private data */
|
||||||
struct _WND_DRIVER *pDriver; /* Window driver */
|
struct _WND_DRIVER *pDriver; /* Window driver */
|
||||||
|
XExposeEvent *expose_event; /* Deferred expose event */
|
||||||
DWORD wExtra[1]; /* Window extra bytes */
|
DWORD wExtra[1]; /* Window extra bytes */
|
||||||
} WND;
|
} WND;
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ static void EVENT_ButtonRelease( WND *pWnd, XButtonEvent *event );
|
||||||
static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event );
|
static void EVENT_MotionNotify( WND *pWnd, XMotionEvent *event );
|
||||||
static void EVENT_FocusIn( WND *pWnd, XFocusChangeEvent *event );
|
static void EVENT_FocusIn( WND *pWnd, XFocusChangeEvent *event );
|
||||||
static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event );
|
static void EVENT_FocusOut( WND *pWnd, XFocusChangeEvent *event );
|
||||||
static void EVENT_Expose( WND *pWnd, XExposeEvent *event );
|
static int EVENT_Expose( WND *pWnd, XExposeEvent *event );
|
||||||
static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
|
static void EVENT_GraphicsExpose( WND *pWnd, XGraphicsExposeEvent *event );
|
||||||
static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event );
|
static void EVENT_ConfigureNotify( WND *pWnd, XConfigureEvent *event );
|
||||||
static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
|
static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
|
||||||
|
@ -110,6 +110,8 @@ static void EVENT_MapNotify( HWND32 hwnd, XMapEvent *event );
|
||||||
static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
|
static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void EVENT_GetGeometry( Window win, int *px, int *py,
|
||||||
|
unsigned int *pwidth, unsigned int *pheight );
|
||||||
static void EVENT_SendMouseEvent( WORD mouseStatus, WORD deltaX, WORD deltaY,
|
static void EVENT_SendMouseEvent( WORD mouseStatus, WORD deltaX, WORD deltaY,
|
||||||
WORD buttonCount, DWORD extraInfo );
|
WORD buttonCount, DWORD extraInfo );
|
||||||
|
|
||||||
|
@ -219,7 +221,23 @@ void EVENT_ProcessEvent( XEvent *event )
|
||||||
|
|
||||||
case Expose:
|
case Expose:
|
||||||
if (!pWnd) return;
|
if (!pWnd) return;
|
||||||
EVENT_Expose( pWnd, (XExposeEvent *)event );
|
if (EVENT_Expose( pWnd, (XExposeEvent *)event )) {
|
||||||
|
/* need to process ConfigureNotify first */
|
||||||
|
XEvent new_event;
|
||||||
|
|
||||||
|
/* attempt to find and process the ConfigureNotify event now */
|
||||||
|
if (TSXCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
|
||||||
|
ConfigureNotify, &new_event)) {
|
||||||
|
EVENT_ProcessEvent( &new_event );
|
||||||
|
EVENT_Expose( pWnd, (XExposeEvent *)event );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no luck at this time, defer Expose event for later */
|
||||||
|
if (!pWnd->expose_event) pWnd->expose_event = malloc( sizeof(XExposeEvent) );
|
||||||
|
else { FIXME(x11,"can't handle more than one deferred Expose events\n"); }
|
||||||
|
*(pWnd->expose_event) = *(XExposeEvent *)event;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GraphicsExpose:
|
case GraphicsExpose:
|
||||||
|
@ -230,6 +248,12 @@ void EVENT_ProcessEvent( XEvent *event )
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
if (!pWnd) return;
|
if (!pWnd) return;
|
||||||
EVENT_ConfigureNotify( pWnd, (XConfigureEvent*)event );
|
EVENT_ConfigureNotify( pWnd, (XConfigureEvent*)event );
|
||||||
|
if (pWnd->expose_event) {
|
||||||
|
/* process deferred Expose event */
|
||||||
|
EVENT_Expose( pWnd, pWnd->expose_event );
|
||||||
|
free( pWnd->expose_event );
|
||||||
|
pWnd->expose_event = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
|
@ -310,6 +334,10 @@ void EVENT_DestroyWindow( WND *pWnd )
|
||||||
{
|
{
|
||||||
XEvent xe;
|
XEvent xe;
|
||||||
|
|
||||||
|
if (pWnd->expose_event) {
|
||||||
|
free( pWnd->expose_event );
|
||||||
|
pWnd->expose_event = NULL;
|
||||||
|
}
|
||||||
TSXDeleteContext( display, pWnd->window, winContext );
|
TSXDeleteContext( display, pWnd->window, winContext );
|
||||||
TSXDestroyWindow( display, pWnd->window );
|
TSXDestroyWindow( display, pWnd->window );
|
||||||
while( TSXCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
|
while( TSXCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
|
||||||
|
@ -626,9 +654,23 @@ static WORD EVENT_XStateToKeyState( int state )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* EVENT_Expose
|
* EVENT_Expose
|
||||||
*/
|
*/
|
||||||
static void EVENT_Expose( WND *pWnd, XExposeEvent *event )
|
static int EVENT_Expose( WND *pWnd, XExposeEvent *event )
|
||||||
{
|
{
|
||||||
RECT32 rect;
|
RECT32 rect;
|
||||||
|
int x, y;
|
||||||
|
unsigned int width, height;
|
||||||
|
|
||||||
|
/* When scrolling, many (fvwm2-based) window managers send the Expose
|
||||||
|
* event before sending the ConfigureNotify event, and we don't like
|
||||||
|
* that, so before processing the Expose event, we check whether the
|
||||||
|
* geometry has changed, and if so, we defer the Expose event until
|
||||||
|
* we get the ConfigureNotify event. -Ove Kåven */
|
||||||
|
EVENT_GetGeometry( event->window, &x, &y, &width, &height );
|
||||||
|
|
||||||
|
if ( x != pWnd->rectWindow.left || y != pWnd->rectWindow.top ||
|
||||||
|
(width != pWnd->rectWindow.right - pWnd->rectWindow.left) ||
|
||||||
|
(height != pWnd->rectWindow.bottom - pWnd->rectWindow.top))
|
||||||
|
return 1; /* tell EVENT_ProcessEvent() to defer it */
|
||||||
|
|
||||||
/* Make position relative to client area instead of window */
|
/* Make position relative to client area instead of window */
|
||||||
rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
|
rect.left = event->x - (pWnd->rectClient.left - pWnd->rectWindow.left);
|
||||||
|
@ -639,6 +681,7 @@ static void EVENT_Expose( WND *pWnd, XExposeEvent *event )
|
||||||
PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
|
PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
|
||||||
RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
|
RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
|
||||||
(event->count ? 0 : RDW_ERASENOW), 0 );
|
(event->count ? 0 : RDW_ERASENOW), 0 );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -438,6 +438,7 @@ BOOL32 WIN_CreateDesktopWindow(void)
|
||||||
pWndDesktop->hSysMenu = 0;
|
pWndDesktop->hSysMenu = 0;
|
||||||
pWndDesktop->userdata = 0;
|
pWndDesktop->userdata = 0;
|
||||||
pWndDesktop->pDriver = &X11DRV_WND_Driver;
|
pWndDesktop->pDriver = &X11DRV_WND_Driver;
|
||||||
|
pWndDesktop->expose_event = NULL;
|
||||||
|
|
||||||
pWndDesktop->winproc = (WNDPROC16)class->winproc;
|
pWndDesktop->winproc = (WNDPROC16)class->winproc;
|
||||||
|
|
||||||
|
@ -574,6 +575,7 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
|
||||||
wndPtr->pHScroll = NULL;
|
wndPtr->pHScroll = NULL;
|
||||||
wndPtr->pProp = NULL;
|
wndPtr->pProp = NULL;
|
||||||
wndPtr->userdata = 0;
|
wndPtr->userdata = 0;
|
||||||
|
wndPtr->expose_event = NULL;
|
||||||
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
|
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
|
||||||
? MENU_GetSysMenu( hwnd, 0 ) : 0;
|
? MENU_GetSysMenu( hwnd, 0 ) : 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue