X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0b5c0e1ac19ac7520dea4477c581dd538e1815b6..f435c1f030721cd3ab023ae346f895924c29c8e8:/src/x11/app.cpp diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 83dbe13466..165942382a 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -25,6 +25,7 @@ #include "wx/log.h" #include "wx/intl.h" #include "wx/evtloop.h" +#include "wx/timer.h" #include "wx/univ/theme.h" #include "wx/univ/renderer.h" @@ -180,8 +181,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 +404,7 @@ bool wxApp::Initialized() int wxApp::MainLoop() { - int rt; + int rt; m_mainLoop = new wxEventLoop; rt = m_mainLoop->Run(); @@ -447,10 +450,10 @@ static Bool expose_predicate (Display *display, XEvent *xevent, XPointer arg) // wxUSE_NANOX //----------------------------------------------------------------------- -// Processes an X event. +// Processes an X event, returning TRUE if the event was processed. //----------------------------------------------------------------------- -void wxApp::ProcessXEvent(WXEvent* _event) +bool wxApp::ProcessXEvent(WXEvent* _event) { XEvent* event = (XEvent*) _event; @@ -466,7 +469,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) win = wxGetWindowFromTable(window); if (!win) - return; + return FALSE; #ifdef __WXDEBUG__ wxString windowClass = win->GetClassInfo()->GetClassName(); @@ -474,35 +477,102 @@ void wxApp::ProcessXEvent(WXEvent* _event) switch (event->type) { + 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 + XEvent tmp_event; + wxExposeInfo info; + info.window = event->xexpose.window; + info.found_non_matching = FALSE; + while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info )) + { + 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 + + // Only erase background, paint in idle time. + win->SendEraseEvents(); + + return TRUE; + } + +#if !wxUSE_NANOX + case GraphicsExpose: + { + // wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(), + // event->xgraphicsexpose.x, event->xgraphicsexpose.y, + // event->xgraphicsexpose.width, event->xgraphicsexpose.height); + + win->GetUpdateRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, + event->xgraphicsexpose.width, event->xgraphicsexpose.height); + + win->GetClearRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, + event->xgraphicsexpose.width, event->xgraphicsexpose.height); + + if (event->xgraphicsexpose.count == 0) + { + // Only erase background, paint in idle time. + win->SendEraseEvents(); + //win->Update(); + } + + return TRUE; + } +#endif + case KeyPress: { if (!win->IsEnabled()) - return; + return FALSE; wxKeyEvent keyEvent(wxEVT_KEY_DOWN); wxTranslateKeyEvent(keyEvent, win, window, event); // wxLogDebug( "OnKey from %s", win->GetName().c_str() ); - // We didn't process wxEVT_KEY_DOWN, so send - // wxEVT_CHAR - if (!win->GetEventHandler()->ProcessEvent( keyEvent )) + // We didn't process wxEVT_KEY_DOWN, so send wxEVT_CHAR + if (win->GetEventHandler()->ProcessEvent( keyEvent )) + return TRUE; + + keyEvent.SetEventType(wxEVT_CHAR); + if (win->GetEventHandler()->ProcessEvent( keyEvent )) + return TRUE; + + if ( (keyEvent.m_keyCode == WXK_TAB) && + win->GetParent() && (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) { - keyEvent.SetEventType(wxEVT_CHAR); - win->GetEventHandler()->ProcessEvent( keyEvent ); + wxNavigationKeyEvent new_event; + new_event.SetEventObject( win->GetParent() ); + /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ + new_event.SetDirection( (keyEvent.m_keyCode == WXK_TAB) ); + /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + new_event.SetWindowChange( keyEvent.ControlDown() ); + new_event.SetCurrentFocus( win ); + return win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); } - return; + + return FALSE; } 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: { @@ -511,23 +581,32 @@ void wxApp::ProcessXEvent(WXEvent* _event) #endif { //wxLogDebug("ConfigureNotify: %s", windowClass.c_str()); - wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() ); - sizeEvent.SetEventObject( win ); + if (win->IsTopLevel() && win->IsShown()) + { + wxTopLevelWindowX11 *tlw = (wxTopLevelWindowX11 *) win; + tlw->SetNeedResizeInIdle(); + } + else + { + 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: { //wxLogDebug("PropertyNotify: %s", windowClass.c_str()); - HandlePropertyChange(_event); - return; + 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); @@ -537,17 +616,31 @@ void wxApp::ProcessXEvent(WXEvent* _event) if ((Atom) (event->xclient.data.l[0]) == wm_delete_window) { win->Close(FALSE); + return TRUE; } } - return; + return FALSE; + } +#if 0 + case DestroyNotify: + { + printf( "destroy from %s\n", win->GetName().c_str() ); + break; + } + case CreateNotify: + { + printf( "create from %s\n", win->GetName().c_str() ); + break; + } + case MapRequest: + { + printf( "map request from %s\n", win->GetName().c_str() ); + break; } case ResizeRequest: { - /* - * If resize event, don't resize until the last resize event for this - * window is recieved. Prevents flicker as windows are resized. - */ - + printf( "resize request from %s\n", win->GetName().c_str() ); + Display *disp = (Display*) wxGetDisplay(); XEvent report; @@ -555,78 +648,25 @@ void wxApp::ProcessXEvent(WXEvent* _event) report = * event; while( XCheckTypedWindowEvent (disp, actualWindow, ResizeRequest, &report)); - if (win) - { - wxSize sz = win->GetSize(); - wxSizeEvent sizeEvent(sz, win->GetId()); - sizeEvent.SetEventObject(win); + wxSize sz = win->GetSize(); + wxSizeEvent sizeEvent(sz, win->GetId()); + sizeEvent.SetEventObject(win); - win->GetEventHandler()->ProcessEvent( sizeEvent ); - } - - return; + return win->GetEventHandler()->ProcessEvent( sizeEvent ); } #endif +#endif #if wxUSE_NANOX case GR_EVENT_TYPE_CLOSE_REQ: { 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 - XEvent tmp_event; - wxExposeInfo info; - info.window = event->xexpose.window; - info.found_non_matching = FALSE; - while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info )) - { - 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; - } -#if !wxUSE_NANOX - case GraphicsExpose: - { - // wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(), - // event->xgraphicsexpose.x, event->xgraphicsexpose.y, - // event->xgraphicsexpose.width, event->xgraphicsexpose.height); - - win->GetUpdateRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, - event->xgraphicsexpose.width, event->xgraphicsexpose.height); - - win->GetClearRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, - event->xgraphicsexpose.width, event->xgraphicsexpose.height); - - if (event->xgraphicsexpose.count == 0) - { - // Only erase background, paint in idle time. - win->SendEraseEvents(); - } - - return; - } #endif case EnterNotify: case LeaveNotify: @@ -635,7 +675,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. @@ -643,25 +683,32 @@ 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(); } } - + +#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: { @@ -677,8 +724,9 @@ void wxApp::ProcessXEvent(WXEvent* _event) focusEvent.SetWindow( g_prevFocus ); g_prevFocus = NULL; - win->GetEventHandler()->ProcessEvent(focusEvent); + return win->GetEventHandler()->ProcessEvent(focusEvent); } + return FALSE; break; } case FocusOut: @@ -694,27 +742,22 @@ 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 - case DestroyNotify: - { - // Do we want to process this (for top-level windows)? - // But we want to be able to veto closes, anyway - break; - } -#endif default: { #ifdef __WXDEBUG__ //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. @@ -749,11 +792,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) @@ -861,7 +905,7 @@ bool wxApp::OnInitGui() delete wxLog::SetActiveTarget(new wxLogStderr); if (!wxAppBase::OnInitGui()) - return FALSE; + return FALSE; GetMainColormap( wxApp::GetDisplay() ); @@ -900,13 +944,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) @@ -950,6 +994,11 @@ bool wxApp::Yield(bool onlyIfNeeded) while (wxTheApp && wxTheApp->Pending()) wxTheApp->Dispatch(); +#if wxUSE_TIMER + wxTimer::NotifyTimers(); +#endif + ProcessIdle(); + s_inYield = FALSE; return TRUE;