From 9d2cef1c694eb0c34ae4b9c9bd7ab04e3255301d Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 24 Feb 2002 13:59:21 +0000 Subject: [PATCH] Done some work on wxFocusEvent::SetWindow(). Enough at least solve the menu problem that dismissed menus when the parent menu (correctly) lost the focus. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14388 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/x11/app.cpp | 174 ++++++++++++++++++++++----------------------- src/x11/window.cpp | 6 +- 2 files changed, 88 insertions(+), 92 deletions(-) diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 39f1eb2d53..58881f9d63 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -37,32 +37,37 @@ #include "wx/resource.h" #endif -#ifdef __VMS__ -#pragma message disable nosimpint -#endif -#include -#include -#include - -#ifdef __VMS__ -#pragma message enable nosimpint -#endif - #include "wx/x11/private.h" #include +//------------------------------------------------------------------------ +// global data +//------------------------------------------------------------------------ + extern wxList wxPendingDelete; +wxHashTable *wxWidgetHashTable = NULL; + wxApp *wxTheApp = NULL; -wxHashTable *wxWidgetHashTable = NULL; +// This is set within wxEntryStart -- too early on +// to put these in wxTheApp +static int g_newArgc = 0; +static wxChar** g_newArgv = NULL; +static bool g_showIconic = FALSE; +static wxSize g_initialSize = wxDefaultSize; -IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) +// This is required for wxFocusEvent::SetWindow(). It will only +// work for focus events which we provoke ourselves (by calling +// SetFocus()). It will not work for those events, which X11 +// generates itself. +static wxWindow *g_nextFocus = NULL; +static wxWindow *g_prevFocus = NULL; -BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) - EVT_IDLE(wxApp::OnIdle) -END_EVENT_TABLE() +//------------------------------------------------------------------------ +// X11 error handling +//------------------------------------------------------------------------ #ifdef __WXDEBUG__ typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *); @@ -79,15 +84,18 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) } #endif // __WXDEBUG__ +//------------------------------------------------------------------------ +// wxApp +//------------------------------------------------------------------------ + long wxApp::sm_lastMessageTime = 0; WXDisplay *wxApp::ms_display = NULL; -// This is set within wxEntryStart -- too early on -// to put these in wxTheApp -static int g_newArgc = 0; -static wxChar** g_newArgv = NULL; -static bool g_showIconic = FALSE; -static wxSize g_initialSize = wxDefaultSize; +IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) + +BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) + EVT_IDLE(wxApp::OnIdle) +END_EVENT_TABLE() bool wxApp::Initialize() { @@ -426,52 +434,39 @@ void wxApp::ProcessXEvent(WXEvent* _event) { case KeyPress: { - if (win && !win->IsEnabled()) + if (!win->IsEnabled()) return; - { - if (win) - { - wxKeyEvent keyEvent(wxEVT_KEY_DOWN); - wxTranslateKeyEvent(keyEvent, win, window, event); + wxKeyEvent keyEvent(wxEVT_KEY_DOWN); + wxTranslateKeyEvent(keyEvent, win, window, event); - // wxLogDebug( "OnKey from %s", win->GetName().c_str() ); + // wxLogDebug( "OnKey from %s", win->GetName().c_str() ); - // We didn't process wxEVT_KEY_DOWN, so send - // wxEVT_CHAR - if (!win->GetEventHandler()->ProcessEvent( keyEvent )) - { - keyEvent.SetEventType(wxEVT_CHAR); - win->GetEventHandler()->ProcessEvent( keyEvent ); - } - - // We intercepted and processed the key down event - return; - } + // We didn't process wxEVT_KEY_DOWN, so send + // wxEVT_CHAR + if (!win->GetEventHandler()->ProcessEvent( keyEvent )) + { + keyEvent.SetEventType(wxEVT_CHAR); + win->GetEventHandler()->ProcessEvent( keyEvent ); } return; } case KeyRelease: { - if (win && !win->IsEnabled()) + if (!win->IsEnabled()) return; - if (win) - { - wxKeyEvent keyEvent(wxEVT_KEY_UP); - wxTranslateKeyEvent(keyEvent, win, window, event); + wxKeyEvent keyEvent(wxEVT_KEY_UP); + wxTranslateKeyEvent(keyEvent, win, window, event); - win->GetEventHandler()->ProcessEvent( keyEvent ); - } + win->GetEventHandler()->ProcessEvent( keyEvent ); return; } case ConfigureNotify: { - if (win #if wxUSE_NANOX - && (event->update.utype == GR_UPDATE_SIZE) + if (event->update.utype == GR_UPDATE_SIZE) #endif - ) { wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() ); sizeEvent.SetEventObject( win ); @@ -487,7 +482,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) } case ClientMessage: { - if (win && !win->IsEnabled()) + if (!win->IsEnabled()) return; Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True); @@ -497,10 +492,7 @@ void wxApp::ProcessXEvent(WXEvent* _event) { if ((Atom) (event->xclient.data.l[0]) == wm_delete_window) { - if (win) - { - win->Close(FALSE); - } + win->Close(FALSE); } } return; @@ -543,21 +535,18 @@ void wxApp::ProcessXEvent(WXEvent* _event) #endif case Expose: { - if (win) - { - win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), - XExposeEventGetWidth(event), XExposeEventGetHeight(event)); + win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), + XExposeEventGetWidth(event), XExposeEventGetHeight(event)); - win->GetClearRegion().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) + if (event->xexpose.count == 0) #endif - { - // Only erase background, paint in idle time. - win->SendEraseEvents(); - } + { + // Only erase background, paint in idle time. + win->SendEraseEvents(); } return; @@ -565,23 +554,20 @@ void wxApp::ProcessXEvent(WXEvent* _event) #if !wxUSE_NANOX case GraphicsExpose: { - if (win) - { - // wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(), - // event->xgraphicsexpose.x, event->xgraphicsexpose.y, - // event->xgraphicsexpose.width, event->xgraphicsexpose.height); + // 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); + 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(); - } + if (event->xgraphicsexpose.count == 0) + { + // Only erase background, paint in idle time. + win->SendEraseEvents(); } return; @@ -593,9 +579,6 @@ void wxApp::ProcessXEvent(WXEvent* _event) case ButtonRelease: case MotionNotify: { - if (!win) - return; - if (!win->IsEnabled()) return; @@ -610,7 +593,14 @@ void wxApp::ProcessXEvent(WXEvent* _event) if (event->type == ButtonPress) { if ((win != wxWindow::FindFocus()) && win->AcceptsFocus()) - win->SetFocus(); + { + // This might actually be done in wxWindow::SetFocus() + // and not here. + g_prevFocus = wxWindow::FindFocus(); + g_nextFocus = win; + + win->SetFocus(); + } } wxMouseEvent wxevent; @@ -621,13 +611,16 @@ void wxApp::ProcessXEvent(WXEvent* _event) case FocusIn: { #if !wxUSE_NANOX - if (win && event->xfocus.detail != NotifyPointer) + if ((event->xfocus.detail != NotifyPointer) && + (event->xfocus.mode == NotifyNormal)) #endif { - // wxLogDebug( "FocusIn from %s", win->GetName().c_str() ); + // wxLogDebug( "FocusIn from %s of type %s", win->GetName().c_str(), win->GetClassInfo()->GetClassName() ); wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId()); focusEvent.SetEventObject(win); + focusEvent.SetWindow( g_prevFocus ); + g_prevFocus = NULL; win->GetEventHandler()->ProcessEvent(focusEvent); } break; @@ -635,13 +628,16 @@ void wxApp::ProcessXEvent(WXEvent* _event) case FocusOut: { #if !wxUSE_NANOX - if (win && event->xfocus.detail != NotifyPointer) + if ((event->xfocus.detail != NotifyPointer) && + (event->xfocus.mode == NotifyNormal)) #endif { - // wxLogDebug( "FocusOut from %s", win->GetName().c_str() ); + // wxLogDebug( "FocusOut from %s of type %s", win->GetName().c_str(), win->GetClassInfo()->GetClassName() ); wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId()); focusEvent.SetEventObject(win); + focusEvent.SetWindow( g_nextFocus ); + g_nextFocus = NULL; win->GetEventHandler()->ProcessEvent(focusEvent); } break; diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 05a8a767f9..cb7c133691 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -636,7 +636,7 @@ void wxWindowX11::DoGetSize(int *x, int *y) const wxCHECK_RET( xwindow, wxT("invalid window") ); - XSync(wxGlobalDisplay(), False); + // XSync(wxGlobalDisplay(), False); XWindowAttributes attr; Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr ); @@ -654,7 +654,7 @@ void wxWindowX11::DoGetPosition(int *x, int *y) const Window window = (Window) m_mainWidget; if (window) { - XSync(wxGlobalDisplay(), False); + // XSync(wxGlobalDisplay(), False); XWindowAttributes attr; Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr); wxASSERT(status); @@ -708,7 +708,7 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const if (window) { - XSync(wxGlobalDisplay(), False); // Is this really a good idea? + // XSync(wxGlobalDisplay(), False); // Is this really a good idea? XWindowAttributes attr; Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr ); wxASSERT(status); -- 2.45.2