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
This commit is contained in:
Robert Roebling 2002-02-24 13:59:21 +00:00
parent 6c0d0845c2
commit 9d2cef1c69
2 changed files with 89 additions and 93 deletions

View File

@ -37,32 +37,37 @@
#include "wx/resource.h" #include "wx/resource.h"
#endif #endif
#ifdef __VMS__
#pragma message disable nosimpint
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#ifdef __VMS__
#pragma message enable nosimpint
#endif
#include "wx/x11/private.h" #include "wx/x11/private.h"
#include <string.h> #include <string.h>
extern wxList wxPendingDelete; //------------------------------------------------------------------------
// global data
//------------------------------------------------------------------------
wxApp *wxTheApp = NULL; extern wxList wxPendingDelete;
wxHashTable *wxWidgetHashTable = NULL; wxHashTable *wxWidgetHashTable = NULL;
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) wxApp *wxTheApp = NULL;
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) // This is set within wxEntryStart -- too early on
EVT_IDLE(wxApp::OnIdle) // to put these in wxTheApp
END_EVENT_TABLE() static int g_newArgc = 0;
static wxChar** g_newArgv = NULL;
static bool g_showIconic = FALSE;
static wxSize g_initialSize = wxDefaultSize;
// 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;
//------------------------------------------------------------------------
// X11 error handling
//------------------------------------------------------------------------
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *); typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *);
@ -79,15 +84,18 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent)
} }
#endif // __WXDEBUG__ #endif // __WXDEBUG__
//------------------------------------------------------------------------
// wxApp
//------------------------------------------------------------------------
long wxApp::sm_lastMessageTime = 0; long wxApp::sm_lastMessageTime = 0;
WXDisplay *wxApp::ms_display = NULL; WXDisplay *wxApp::ms_display = NULL;
// This is set within wxEntryStart -- too early on IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
// to put these in wxTheApp
static int g_newArgc = 0; BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
static wxChar** g_newArgv = NULL; EVT_IDLE(wxApp::OnIdle)
static bool g_showIconic = FALSE; END_EVENT_TABLE()
static wxSize g_initialSize = wxDefaultSize;
bool wxApp::Initialize() bool wxApp::Initialize()
{ {
@ -426,52 +434,39 @@ void wxApp::ProcessXEvent(WXEvent* _event)
{ {
case KeyPress: case KeyPress:
{ {
if (win && !win->IsEnabled()) if (!win->IsEnabled())
return; return;
{ wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
if (win) 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 // We didn't process wxEVT_KEY_DOWN, so send
// wxEVT_CHAR // wxEVT_CHAR
if (!win->GetEventHandler()->ProcessEvent( keyEvent )) if (!win->GetEventHandler()->ProcessEvent( keyEvent ))
{ {
keyEvent.SetEventType(wxEVT_CHAR); keyEvent.SetEventType(wxEVT_CHAR);
win->GetEventHandler()->ProcessEvent( keyEvent ); win->GetEventHandler()->ProcessEvent( keyEvent );
}
// We intercepted and processed the key down event
return;
}
} }
return; return;
} }
case KeyRelease: case KeyRelease:
{ {
if (win && !win->IsEnabled()) if (!win->IsEnabled())
return; 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; return;
} }
case ConfigureNotify: case ConfigureNotify:
{ {
if (win
#if wxUSE_NANOX #if wxUSE_NANOX
&& (event->update.utype == GR_UPDATE_SIZE) if (event->update.utype == GR_UPDATE_SIZE)
#endif #endif
)
{ {
wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() ); wxSizeEvent sizeEvent( wxSize(XConfigureEventGetWidth(event), XConfigureEventGetHeight(event)), win->GetId() );
sizeEvent.SetEventObject( win ); sizeEvent.SetEventObject( win );
@ -487,7 +482,7 @@ void wxApp::ProcessXEvent(WXEvent* _event)
} }
case ClientMessage: case ClientMessage:
{ {
if (win && !win->IsEnabled()) if (!win->IsEnabled())
return; return;
Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", True); 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 ((Atom) (event->xclient.data.l[0]) == wm_delete_window)
{ {
if (win) win->Close(FALSE);
{
win->Close(FALSE);
}
} }
} }
return; return;
@ -543,21 +535,18 @@ void wxApp::ProcessXEvent(WXEvent* _event)
#endif #endif
case Expose: 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), win->GetClearRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
XExposeEventGetWidth(event), XExposeEventGetHeight(event)); XExposeEventGetWidth(event), XExposeEventGetHeight(event));
#if !wxUSE_NANOX #if !wxUSE_NANOX
if (event->xexpose.count == 0) if (event->xexpose.count == 0)
#endif #endif
{ {
// Only erase background, paint in idle time. // Only erase background, paint in idle time.
win->SendEraseEvents(); win->SendEraseEvents();
}
} }
return; return;
@ -565,23 +554,20 @@ void wxApp::ProcessXEvent(WXEvent* _event)
#if !wxUSE_NANOX #if !wxUSE_NANOX
case GraphicsExpose: case GraphicsExpose:
{ {
if (win) // wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(),
{ // event->xgraphicsexpose.x, event->xgraphicsexpose.y,
// wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(), // event->xgraphicsexpose.width, event->xgraphicsexpose.height);
// event->xgraphicsexpose.x, event->xgraphicsexpose.y,
// event->xgraphicsexpose.width, event->xgraphicsexpose.height);
win->GetUpdateRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, win->GetUpdateRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y,
event->xgraphicsexpose.width, event->xgraphicsexpose.height); event->xgraphicsexpose.width, event->xgraphicsexpose.height);
win->GetClearRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y,
event->xgraphicsexpose.width, event->xgraphicsexpose.height);
win->GetClearRegion().Union( event->xgraphicsexpose.x, event->xgraphicsexpose.y, if (event->xgraphicsexpose.count == 0)
event->xgraphicsexpose.width, event->xgraphicsexpose.height); {
// Only erase background, paint in idle time.
if (event->xgraphicsexpose.count == 0) win->SendEraseEvents();
{
// Only erase background, paint in idle time.
win->SendEraseEvents();
}
} }
return; return;
@ -593,9 +579,6 @@ void wxApp::ProcessXEvent(WXEvent* _event)
case ButtonRelease: case ButtonRelease:
case MotionNotify: case MotionNotify:
{ {
if (!win)
return;
if (!win->IsEnabled()) if (!win->IsEnabled())
return; return;
@ -610,7 +593,14 @@ void wxApp::ProcessXEvent(WXEvent* _event)
if (event->type == ButtonPress) if (event->type == ButtonPress)
{ {
if ((win != wxWindow::FindFocus()) && win->AcceptsFocus()) 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; wxMouseEvent wxevent;
@ -621,13 +611,16 @@ void wxApp::ProcessXEvent(WXEvent* _event)
case FocusIn: case FocusIn:
{ {
#if !wxUSE_NANOX #if !wxUSE_NANOX
if (win && event->xfocus.detail != NotifyPointer) if ((event->xfocus.detail != NotifyPointer) &&
(event->xfocus.mode == NotifyNormal))
#endif #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()); wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId());
focusEvent.SetEventObject(win); focusEvent.SetEventObject(win);
focusEvent.SetWindow( g_prevFocus );
g_prevFocus = NULL;
win->GetEventHandler()->ProcessEvent(focusEvent); win->GetEventHandler()->ProcessEvent(focusEvent);
} }
break; break;
@ -635,13 +628,16 @@ void wxApp::ProcessXEvent(WXEvent* _event)
case FocusOut: case FocusOut:
{ {
#if !wxUSE_NANOX #if !wxUSE_NANOX
if (win && event->xfocus.detail != NotifyPointer) if ((event->xfocus.detail != NotifyPointer) &&
(event->xfocus.mode == NotifyNormal))
#endif #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()); wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId());
focusEvent.SetEventObject(win); focusEvent.SetEventObject(win);
focusEvent.SetWindow( g_nextFocus );
g_nextFocus = NULL;
win->GetEventHandler()->ProcessEvent(focusEvent); win->GetEventHandler()->ProcessEvent(focusEvent);
} }
break; break;

View File

@ -636,7 +636,7 @@ void wxWindowX11::DoGetSize(int *x, int *y) const
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
XSync(wxGlobalDisplay(), False); // XSync(wxGlobalDisplay(), False);
XWindowAttributes attr; XWindowAttributes attr;
Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr ); Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr );
@ -654,7 +654,7 @@ void wxWindowX11::DoGetPosition(int *x, int *y) const
Window window = (Window) m_mainWidget; Window window = (Window) m_mainWidget;
if (window) if (window)
{ {
XSync(wxGlobalDisplay(), False); // XSync(wxGlobalDisplay(), False);
XWindowAttributes attr; XWindowAttributes attr;
Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr); Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr);
wxASSERT(status); wxASSERT(status);
@ -708,7 +708,7 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const
if (window) if (window)
{ {
XSync(wxGlobalDisplay(), False); // Is this really a good idea? // XSync(wxGlobalDisplay(), False); // Is this really a good idea?
XWindowAttributes attr; XWindowAttributes attr;
Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr ); Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr );
wxASSERT(status); wxASSERT(status);