X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9d2cef1c694eb0c34ae4b9c9bd7ab04e3255301d..cd560c961a09a8ae80b9c32856e195ed784cc547:/src/x11/app.cpp diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 58881f9d63..34416b4f9b 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -180,8 +180,10 @@ void wxApp::CleanUp() int wxEntryStart( int& argc, char *argv[] ) { #ifdef __WXDEBUG__ +#if !wxUSE_NANOX // install the X error handler gs_pfnXErrorHandler = XSetErrorHandler( wxXErrorHandler ); +#endif #endif // __WXDEBUG__ wxString displayName; @@ -401,7 +403,7 @@ bool wxApp::Initialized() int wxApp::MainLoop() { - int rt; + int rt; m_mainLoop = new wxEventLoop; rt = m_mainLoop->Run(); @@ -411,15 +413,53 @@ int wxApp::MainLoop() return rt; } -// Processes an X event. -void wxApp::ProcessXEvent(WXEvent* _event) +#if !wxUSE_NANOX +//----------------------------------------------------------------------- +// X11 predicate function for exposure compression +//----------------------------------------------------------------------- + +struct wxExposeInfo +{ + Window window; + Bool found_non_matching; +}; + +static Bool expose_predicate (Display *display, XEvent *xevent, XPointer arg) +{ + wxExposeInfo *info = (wxExposeInfo*) arg; + + if (info->found_non_matching) + return FALSE; + + if (xevent->xany.type != Expose) + { + info->found_non_matching = TRUE; + return FALSE; + } + + if (xevent->xexpose.window != info->window) + { + info->found_non_matching = TRUE; + return FALSE; + } + + return TRUE; +} +#endif + // wxUSE_NANOX + +//----------------------------------------------------------------------- +// Processes an X event, returning TRUE if the event was processed. +//----------------------------------------------------------------------- + +bool wxApp::ProcessXEvent(WXEvent* _event) { XEvent* event = (XEvent*) _event; wxWindow* win = NULL; Window window = XEventGetWindow(event); Window actualWindow = window; - + // Find the first wxWindow that corresponds to this event window // Because we're receiving events after a window // has been destroyed, assume a 1:1 match between @@ -428,14 +468,18 @@ void wxApp::ProcessXEvent(WXEvent* _event) win = wxGetWindowFromTable(window); if (!win) - return; + return FALSE; +#ifdef __WXDEBUG__ + wxString windowClass = win->GetClassInfo()->GetClassName(); +#endif + switch (event->type) { case KeyPress: { if (!win->IsEnabled()) - return; + return FALSE; wxKeyEvent keyEvent(wxEVT_KEY_DOWN); wxTranslateKeyEvent(keyEvent, win, window, event); @@ -447,20 +491,20 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (!win->GetEventHandler()->ProcessEvent( keyEvent )) { keyEvent.SetEventType(wxEVT_CHAR); - win->GetEventHandler()->ProcessEvent( keyEvent ); + if (!win->GetEventHandler()->ProcessEvent( keyEvent )) + return FALSE; } - return; + return TRUE; } case KeyRelease: { if (!win->IsEnabled()) - return; + return FALSE; wxKeyEvent keyEvent(wxEVT_KEY_UP); wxTranslateKeyEvent(keyEvent, win, window, event); - win->GetEventHandler()->ProcessEvent( keyEvent ); - return; + return win->GetEventHandler()->ProcessEvent( keyEvent ); } case ConfigureNotify: { @@ -468,22 +512,25 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (event->update.utype == GR_UPDATE_SIZE) #endif { + //wxLogDebug("ConfigureNotify: %s", windowClass.c_str()); wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() ); sizeEvent.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( sizeEvent ); + return win->GetEventHandler()->ProcessEvent( sizeEvent ); } + return FALSE; + break; } #if !wxUSE_NANOX case PropertyNotify: { - HandlePropertyChange(_event); - return; + //wxLogDebug("PropertyNotify: %s", windowClass.c_str()); + return HandlePropertyChange(_event); } case ClientMessage: { if (!win->IsEnabled()) - return; + return FALSE; Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True); Atom wm_protocols = XInternAtom(wxGlobalDisplay(), "WM_PROTOCOLS", True); @@ -493,9 +540,10 @@ void wxApp::ProcessXEvent(WXEvent* _event) if ((Atom) (event->xclient.data.l[0]) == wm_delete_window) { win->Close(FALSE); + return TRUE; } } - return; + return FALSE; } case ResizeRequest: { @@ -517,10 +565,10 @@ void wxApp::ProcessXEvent(WXEvent* _event) wxSizeEvent sizeEvent(sz, win->GetId()); sizeEvent.SetEventObject(win); - win->GetEventHandler()->ProcessEvent( sizeEvent ); + return win->GetEventHandler()->ProcessEvent( sizeEvent ); } - return; + return FALSE; } #endif #if wxUSE_NANOX @@ -529,27 +577,40 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (win) { win->Close(FALSE); + return TRUE; } + return FALSE; break; } #endif case Expose: { + //wxLogDebug("Expose: %s", windowClass.c_str()); win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), XExposeEventGetWidth(event), XExposeEventGetHeight(event)); win->GetClearRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), XExposeEventGetWidth(event), XExposeEventGetHeight(event)); + #if !wxUSE_NANOX - if (event->xexpose.count == 0) -#endif + XEvent tmp_event; + wxExposeInfo info; + info.window = event->xexpose.window; + info.found_non_matching = FALSE; + while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info )) { - // Only erase background, paint in idle time. - win->SendEraseEvents(); + win->GetUpdateRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y, + tmp_event.xexpose.width, tmp_event.xexpose.height ); + + win->GetClearRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y, + tmp_event.xexpose.width, tmp_event.xexpose.height ); } +#endif + + win->SendEraseEvents(); - return; + return TRUE; } #if !wxUSE_NANOX case GraphicsExpose: @@ -570,7 +631,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) win->SendEraseEvents(); } - return; + return TRUE; } #endif case EnterNotify: @@ -580,7 +641,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) case MotionNotify: { if (!win->IsEnabled()) - return; + return FALSE; // Here we check if the top level window is // disabled, which is one aspect of modality. @@ -588,25 +649,33 @@ void wxApp::ProcessXEvent(WXEvent* _event) while (tlw && !tlw->IsTopLevel()) tlw = tlw->GetParent(); if (tlw && !tlw->IsEnabled()) - return; - + return FALSE; + if (event->type == ButtonPress) { if ((win != wxWindow::FindFocus()) && win->AcceptsFocus()) { // This might actually be done in wxWindow::SetFocus() - // and not here. + // and not here. TODO. g_prevFocus = wxWindow::FindFocus(); g_nextFocus = win; win->SetFocus(); + // return TRUE; } } - + +#if !wxUSE_NANOX + if (event->type == LeaveNotify || event->type == EnterNotify) + { + // Throw out NotifyGrab and NotifyUngrab + if (event->xcrossing.mode != NotifyNormal) + return FALSE; + } +#endif wxMouseEvent wxevent; wxTranslateMouseEvent(wxevent, win, window, event); - win->GetEventHandler()->ProcessEvent( wxevent ); - return; + return win->GetEventHandler()->ProcessEvent( wxevent ); } case FocusIn: { @@ -621,8 +690,10 @@ void wxApp::ProcessXEvent(WXEvent* _event) focusEvent.SetEventObject(win); focusEvent.SetWindow( g_prevFocus ); g_prevFocus = NULL; - win->GetEventHandler()->ProcessEvent(focusEvent); + + return win->GetEventHandler()->ProcessEvent(focusEvent); } + return FALSE; break; } case FocusOut: @@ -638,8 +709,9 @@ void wxApp::ProcessXEvent(WXEvent* _event) focusEvent.SetEventObject(win); focusEvent.SetWindow( g_nextFocus ); g_nextFocus = NULL; - win->GetEventHandler()->ProcessEvent(focusEvent); + return win->GetEventHandler()->ProcessEvent(focusEvent); } + return FALSE; break; } #ifndef wxUSE_NANOX @@ -647,6 +719,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) { // Do we want to process this (for top-level windows)? // But we want to be able to veto closes, anyway + return FALSE; break; } #endif @@ -656,9 +729,11 @@ void wxApp::ProcessXEvent(WXEvent* _event) //wxString eventName = wxGetXEventName(XEvent& event); //wxLogDebug(wxT("Event %s not handled"), eventName.c_str()); #endif + return FALSE; break; } } + return FALSE; } // Returns TRUE if more time is needed. @@ -693,11 +768,12 @@ void wxApp::Dispatch() // This should be redefined in a derived class for // handling property change events for XAtom IPC. -void wxApp::HandlePropertyChange(WXEvent *event) +bool wxApp::HandlePropertyChange(WXEvent *event) { // by default do nothing special // TODO: what to do for X11 // XtDispatchEvent((XEvent*) event); + return FALSE; } void wxApp::OnIdle(wxIdleEvent& event) @@ -805,7 +881,7 @@ bool wxApp::OnInitGui() delete wxLog::SetActiveTarget(new wxLogStderr); if (!wxAppBase::OnInitGui()) - return FALSE; + return FALSE; GetMainColormap( wxApp::GetDisplay() ); @@ -844,13 +920,13 @@ Window wxGetWindowParent(Window window) #endif Window* children = NULL; - // #define XQueryTree(d,w,r,p,c,nc) GrQueryTree(w,p,c,nc) + // #define XQueryTree(d,w,r,p,c,nc) GrQueryTree(w,p,c,nc) int res = 1; #if !wxUSE_NANOX res = #endif XQueryTree((Display*) wxGetDisplay(), window, & root, & parent, - & children, & noChildren); + & children, & noChildren); if (children) XFree(children); if (res)