X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c978d36124197b5612a2cabefed7591ad0eea6e2..24bcaec36746abeeb9e2023d03e3ab4289006fc3:/src/x11/app.cpp diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 34416b4f9b..e1a0d8027e 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" @@ -48,6 +49,7 @@ extern wxList wxPendingDelete; wxHashTable *wxWidgetHashTable = NULL; +wxHashTable *wxClientWidgetHashTable = NULL; wxApp *wxTheApp = NULL; @@ -118,6 +120,7 @@ bool wxApp::Initialize() #endif wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); + wxClientWidgetHashTable = new wxHashTable(wxKEY_INTEGER); wxModule::RegisterModules(); if (!wxModule::InitializeModules()) return FALSE; @@ -133,6 +136,8 @@ void wxApp::CleanUp() delete wxWidgetHashTable; wxWidgetHashTable = NULL; + delete wxClientWidgetHashTable; + wxClientWidgetHashTable = NULL; wxModule::CleanUpModules(); @@ -465,10 +470,16 @@ bool wxApp::ProcessXEvent(WXEvent* _event) // has been destroyed, assume a 1:1 match between // Window and wxWindow, so if it's not in the table, // it must have been destroyed. - + win = wxGetWindowFromTable(window); if (!win) - return FALSE; + { +#if wxUSE_TWO_WINDOWS + win = wxGetClientWindowFromTable(window); + if (!win) +#endif + return FALSE; + } #ifdef __WXDEBUG__ wxString windowClass = win->GetClassInfo()->GetClassName(); @@ -476,6 +487,79 @@ bool wxApp::ProcessXEvent(WXEvent* _event) switch (event->type) { + case Expose: + { +#if wxUSE_TWO_WINDOWS + if (event->xexpose.window != (Window)win->GetClientWindow()) + { + XEvent tmp_event; + wxExposeInfo info; + info.window = event->xexpose.window; + info.found_non_matching = FALSE; + while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info )) + { + // Don't worry about optimizing redrawing the border etc. + } + win->NeedUpdateNcAreaInIdle(); + } + else +#endif + { + 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 + if (win->GetMainWindow() == win->GetClientWindow()) + win->NeedUpdateNcAreaInIdle(); + + // Only erase background, paint in idle time. + win->SendEraseEvents(); + //win->Update(); + } + + 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()) @@ -486,15 +570,28 @@ bool wxApp::ProcessXEvent(WXEvent* _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); - if (!win->GetEventHandler()->ProcessEvent( keyEvent )) - return FALSE; + 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 TRUE; + + return FALSE; } case KeyRelease: { @@ -512,11 +609,18 @@ bool 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 ); + if (win->IsTopLevel() && win->IsShown()) + { + wxTopLevelWindowX11 *tlw = (wxTopLevelWindowX11 *) win; + tlw->SetNeedResizeInIdle(); + } + else + { + wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() ); + sizeEvent.SetEventObject( win ); - return win->GetEventHandler()->ProcessEvent( sizeEvent ); + return win->GetEventHandler()->ProcessEvent( sizeEvent ); + } } return FALSE; break; @@ -545,13 +649,26 @@ bool wxApp::ProcessXEvent(WXEvent* _event) } 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; @@ -559,18 +676,14 @@ bool 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); - - return win->GetEventHandler()->ProcessEvent( sizeEvent ); - } + wxSize sz = win->GetSize(); + wxSizeEvent sizeEvent(sz, win->GetId()); + sizeEvent.SetEventObject(win); - return FALSE; + return win->GetEventHandler()->ProcessEvent( sizeEvent ); } #endif +#endif #if wxUSE_NANOX case GR_EVENT_TYPE_CLOSE_REQ: { @@ -582,57 +695,6 @@ bool wxApp::ProcessXEvent(WXEvent* _event) 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 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(); - } - - return TRUE; - } #endif case EnterNotify: case LeaveNotify: @@ -661,7 +723,6 @@ bool wxApp::ProcessXEvent(WXEvent* _event) g_nextFocus = win; win->SetFocus(); - // return TRUE; } } @@ -714,15 +775,6 @@ bool wxApp::ProcessXEvent(WXEvent* _event) 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 - return FALSE; - break; - } -#endif default: { #ifdef __WXDEBUG__ @@ -967,19 +1019,35 @@ bool wxApp::Yield(bool onlyIfNeeded) s_inYield = TRUE; + // Make sure we have an event loop object, + // or Pending/Dispatch will fail + wxEventLoop* eventLoop = wxEventLoop::GetActive(); + wxEventLoop* newEventLoop = NULL; + if (!eventLoop) + { + newEventLoop = new wxEventLoop; + wxEventLoop::SetActive(newEventLoop); + } + while (wxTheApp && wxTheApp->Pending()) wxTheApp->Dispatch(); +#if wxUSE_TIMER + wxTimer::NotifyTimers(); +#endif + ProcessIdle(); + + if (newEventLoop) + { + wxEventLoop::SetActive(NULL); + delete newEventLoop; + } + s_inYield = FALSE; return TRUE; } -wxIcon wxApp::GetStdIcon(int which) const -{ - return wxTheme::Get()->GetRenderer()->GetStdIcon(which); -} - void wxApp::OnAssert(const wxChar *file, int line, const wxChar *msg) { // While the GUI isn't working that well, just print out the