Make wxSetInputFocusToXWindow a member instead of free function
Also add a couple of workarounds for problems when using Xvfb. See https://github.com/wxWidgets/wxWidgets/pull/1845
This commit is contained in:
committed by
Vadim Zeitlin
parent
609f77ff55
commit
a3e264e8a3
@@ -25,33 +25,16 @@
|
|||||||
#include <X11/extensions/XTest.h>
|
#include <X11/extensions/XTest.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/log.h"
|
||||||
|
#include "wx/window.h" // for wxGetActiveWindow
|
||||||
#include "wx/unix/utilsx11.h"
|
#include "wx/unix/utilsx11.h"
|
||||||
|
|
||||||
#ifdef __WXGTK20__
|
#ifdef __WXGTK20__
|
||||||
#include "wx/window.h"
|
|
||||||
#include "wx/gtk/private/wrapgtk.h"
|
#include "wx/gtk/private/wrapgtk.h"
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
|
|
||||||
GtkWidget* wxGetTopLevelGTK();
|
GtkWidget* wxGetTopLevelGTK();
|
||||||
GdkWindow* wxGetTopLevelGDK();
|
GdkWindow* wxGetTopLevelGDK();
|
||||||
|
|
||||||
// This helper function tries to set the input focus to the correct (top level)
|
|
||||||
// window, i.e.: the window to which keyboard events will be reported.
|
|
||||||
static inline void wxSetInputFocusToXWindow(wxX11Display& display)
|
|
||||||
{
|
|
||||||
wxWindow* const win = wxGetActiveWindow();
|
|
||||||
|
|
||||||
GdkWindow* gdkwin;
|
|
||||||
|
|
||||||
if ( win && win->IsTopLevel() )
|
|
||||||
gdkwin = gtk_widget_get_window(win->GetHandle());
|
|
||||||
else
|
|
||||||
gdkwin = wxGetTopLevelGDK();
|
|
||||||
|
|
||||||
XSetInputFocus(display, GDK_WINDOW_XID(gdkwin), RevertToPointerRoot, CurrentTime);
|
|
||||||
}
|
|
||||||
#else // !__WXGTK__
|
|
||||||
#define wxSetInputFocusToXWindow(display)
|
|
||||||
#endif // __WXGTK__
|
#endif // __WXGTK__
|
||||||
|
|
||||||
// Normally we fall back on "plain X" implementation if XTest is not available,
|
// Normally we fall back on "plain X" implementation if XTest is not available,
|
||||||
@@ -147,7 +130,53 @@ protected:
|
|||||||
wxYield();
|
wxYield();
|
||||||
wxMilliSleep(50);
|
wxMilliSleep(50);
|
||||||
|
|
||||||
wxSetInputFocusToXWindow(m_display);
|
SetInputFocusToXWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This helper function tries to set the input focus to the active (top level)
|
||||||
|
// window, i.e.: the window to which keyboard events will be reported.
|
||||||
|
//
|
||||||
|
// Normally we would expect the input focus to be correctly set by the WM.
|
||||||
|
// But for some reasons, the input focus is set to PointerRoot under Xvfb,
|
||||||
|
// which means: all keyboard events are forewarded to whatever is underneath
|
||||||
|
// mouse pointer. and consequently, our fake events could be simply lost and
|
||||||
|
// do not reach the subject window at all.
|
||||||
|
void SetInputFocusToXWindow()
|
||||||
|
{
|
||||||
|
Window focus;
|
||||||
|
int revert_to; // dummy
|
||||||
|
|
||||||
|
XGetInputFocus(m_display, &focus, &revert_to);
|
||||||
|
|
||||||
|
if ( focus != PointerRoot && focus != None )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxWindow* win = wxGetActiveWindow();
|
||||||
|
|
||||||
|
#if defined(__WXGTK__)
|
||||||
|
if ( win && !win->IsTopLevel() )
|
||||||
|
{
|
||||||
|
win = wxGetTopLevelParent(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkWindow* gdkwin;
|
||||||
|
|
||||||
|
if ( win )
|
||||||
|
gdkwin = gtk_widget_get_window(win->GetHandle());
|
||||||
|
else
|
||||||
|
gdkwin = wxGetTopLevelGDK();
|
||||||
|
|
||||||
|
focus = GDK_WINDOW_XID(gdkwin);
|
||||||
|
#elif defined(__WXX11__)
|
||||||
|
if ( !win )
|
||||||
|
return;
|
||||||
|
|
||||||
|
focus = (Window)(win->GetHandle());
|
||||||
|
#endif // __WXGTK__
|
||||||
|
|
||||||
|
wxLogTrace("focus", "SetInputFocusToXWindow on Window 0x%ul.", focus);
|
||||||
|
|
||||||
|
XSetInputFocus(m_display, focus, RevertToPointerRoot, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxX11Display m_display;
|
wxX11Display m_display;
|
||||||
|
@@ -584,6 +584,10 @@ void MenuTestCase::Events()
|
|||||||
// Invoke the accelerator.
|
// Invoke the accelerator.
|
||||||
m_frame->Show();
|
m_frame->Show();
|
||||||
m_frame->SetFocus();
|
m_frame->SetFocus();
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
// Without this, test fails when run with other tests under Xvfb.
|
||||||
|
m_frame->Raise();
|
||||||
|
#endif
|
||||||
wxYield();
|
wxYield();
|
||||||
|
|
||||||
wxUIActionSimulator sim;
|
wxUIActionSimulator sim;
|
||||||
|
@@ -211,6 +211,16 @@ void NumValidatorTestCase::Interactive()
|
|||||||
return;
|
return;
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
// Travis CI fails without this!
|
||||||
|
if ( IsAutomaticTest() )
|
||||||
|
{
|
||||||
|
wxFrame* frame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
|
||||||
|
frame->SetFocus();
|
||||||
|
frame->Raise();
|
||||||
|
}
|
||||||
|
#endif // __WXGTK20__
|
||||||
|
|
||||||
// Set a locale using comma as thousands separator character.
|
// Set a locale using comma as thousands separator character.
|
||||||
wxLocale loc(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT);
|
wxLocale loc(wxLANGUAGE_ENGLISH_UK, wxLOCALE_DONT_LOAD_DEFAULT);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user