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:
108
src/x11/app.cpp
108
src/x11/app.cpp
@@ -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,12 +434,9 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
{
|
{
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
{
|
{
|
||||||
if (win && !win->IsEnabled())
|
if (!win->IsEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
|
||||||
if (win)
|
|
||||||
{
|
|
||||||
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
|
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
|
||||||
wxTranslateKeyEvent(keyEvent, win, window, event);
|
wxTranslateKeyEvent(keyEvent, win, window, event);
|
||||||
|
|
||||||
@@ -444,34 +449,24 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
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);
|
wxKeyEvent keyEvent(wxEVT_KEY_UP);
|
||||||
wxTranslateKeyEvent(keyEvent, win, window, event);
|
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);
|
||||||
@@ -496,13 +491,10 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
if (event->xclient.message_type == wm_protocols)
|
if (event->xclient.message_type == wm_protocols)
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
case ResizeRequest:
|
case ResizeRequest:
|
||||||
@@ -542,8 +534,6 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case Expose:
|
case Expose:
|
||||||
{
|
|
||||||
if (win)
|
|
||||||
{
|
{
|
||||||
win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
|
win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
|
||||||
XExposeEventGetWidth(event), XExposeEventGetHeight(event));
|
XExposeEventGetWidth(event), XExposeEventGetHeight(event));
|
||||||
@@ -558,14 +548,11 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
// Only erase background, paint in idle time.
|
// Only erase background, paint in idle time.
|
||||||
win->SendEraseEvents();
|
win->SendEraseEvents();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if !wxUSE_NANOX
|
#if !wxUSE_NANOX
|
||||||
case GraphicsExpose:
|
case GraphicsExpose:
|
||||||
{
|
|
||||||
if (win)
|
|
||||||
{
|
{
|
||||||
// wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(),
|
// wxLogDebug( "GraphicsExpose from %s", win->GetName().c_str(),
|
||||||
// event->xgraphicsexpose.x, event->xgraphicsexpose.y,
|
// event->xgraphicsexpose.x, event->xgraphicsexpose.y,
|
||||||
@@ -582,7 +569,6 @@ void wxApp::ProcessXEvent(WXEvent* _event)
|
|||||||
// Only erase background, paint in idle time.
|
// Only erase background, paint in idle time.
|
||||||
win->SendEraseEvents();
|
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,8 +593,15 @@ 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())
|
||||||
|
{
|
||||||
|
// This might actually be done in wxWindow::SetFocus()
|
||||||
|
// and not here.
|
||||||
|
g_prevFocus = wxWindow::FindFocus();
|
||||||
|
g_nextFocus = win;
|
||||||
|
|
||||||
win->SetFocus();
|
win->SetFocus();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wxMouseEvent wxevent;
|
wxMouseEvent wxevent;
|
||||||
wxTranslateMouseEvent(wxevent, win, window, event);
|
wxTranslateMouseEvent(wxevent, win, window, event);
|
||||||
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user