Merge branch 'uisim-xtest'
Make wxUIActionSimulator work with GTK+3, including when using DPI scaling.
This commit is contained in:
141
configure
vendored
141
configure
vendored
@@ -945,6 +945,8 @@ WEBKIT_LIBS
|
|||||||
WEBKIT_CFLAGS
|
WEBKIT_CFLAGS
|
||||||
COND_PYTHON
|
COND_PYTHON
|
||||||
PYTHON
|
PYTHON
|
||||||
|
XTST_LIBS
|
||||||
|
XTST_CFLAGS
|
||||||
LIBNOTIFY_LIBS
|
LIBNOTIFY_LIBS
|
||||||
LIBNOTIFY_CFLAGS
|
LIBNOTIFY_CFLAGS
|
||||||
GNOMEVFS_LIBS
|
GNOMEVFS_LIBS
|
||||||
@@ -1094,6 +1096,7 @@ with_gtkprint
|
|||||||
with_gnomevfs
|
with_gnomevfs
|
||||||
with_libnotify
|
with_libnotify
|
||||||
with_opengl
|
with_opengl
|
||||||
|
with_xtest
|
||||||
with_dmalloc
|
with_dmalloc
|
||||||
with_sdl
|
with_sdl
|
||||||
with_regex
|
with_regex
|
||||||
@@ -1402,6 +1405,8 @@ GNOMEVFS_CFLAGS
|
|||||||
GNOMEVFS_LIBS
|
GNOMEVFS_LIBS
|
||||||
LIBNOTIFY_CFLAGS
|
LIBNOTIFY_CFLAGS
|
||||||
LIBNOTIFY_LIBS
|
LIBNOTIFY_LIBS
|
||||||
|
XTST_CFLAGS
|
||||||
|
XTST_LIBS
|
||||||
WEBKIT_CFLAGS
|
WEBKIT_CFLAGS
|
||||||
WEBKIT_LIBS
|
WEBKIT_LIBS
|
||||||
CAIRO_CFLAGS
|
CAIRO_CFLAGS
|
||||||
@@ -2324,6 +2329,7 @@ Optional Packages:
|
|||||||
--with-gnomevfs use GNOME VFS for associating MIME types
|
--with-gnomevfs use GNOME VFS for associating MIME types
|
||||||
--with-libnotify use libnotify for notifications
|
--with-libnotify use libnotify for notifications
|
||||||
--with-opengl use OpenGL (or Mesa)
|
--with-opengl use OpenGL (or Mesa)
|
||||||
|
--with-xtest use XTest extension
|
||||||
--with-dmalloc use dmalloc library (http://dmalloc.com/)
|
--with-dmalloc use dmalloc library (http://dmalloc.com/)
|
||||||
--with-sdl use SDL for audio on Unix
|
--with-sdl use SDL for audio on Unix
|
||||||
--with-regex enable support for wxRegEx class
|
--with-regex enable support for wxRegEx class
|
||||||
@@ -2401,6 +2407,8 @@ Some influential environment variables:
|
|||||||
C compiler flags for LIBNOTIFY, overriding pkg-config
|
C compiler flags for LIBNOTIFY, overriding pkg-config
|
||||||
LIBNOTIFY_LIBS
|
LIBNOTIFY_LIBS
|
||||||
linker flags for LIBNOTIFY, overriding pkg-config
|
linker flags for LIBNOTIFY, overriding pkg-config
|
||||||
|
XTST_CFLAGS C compiler flags for XTST, overriding pkg-config
|
||||||
|
XTST_LIBS linker flags for XTST, overriding pkg-config
|
||||||
WEBKIT_CFLAGS
|
WEBKIT_CFLAGS
|
||||||
C compiler flags for WEBKIT, overriding pkg-config
|
C compiler flags for WEBKIT, overriding pkg-config
|
||||||
WEBKIT_LIBS linker flags for WEBKIT, overriding pkg-config
|
WEBKIT_LIBS linker flags for WEBKIT, overriding pkg-config
|
||||||
@@ -4833,6 +4841,35 @@ fi
|
|||||||
eval "$wx_cv_use_opengl"
|
eval "$wx_cv_use_opengl"
|
||||||
|
|
||||||
|
|
||||||
|
withstring=
|
||||||
|
defaultval=$wxUSE_ALL_FEATURES
|
||||||
|
if test -z "$defaultval"; then
|
||||||
|
if test x"$withstring" = xwithout; then
|
||||||
|
defaultval=yes
|
||||||
|
else
|
||||||
|
defaultval=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check whether --with-xtest was given.
|
||||||
|
if test "${with_xtest+set}" = set; then :
|
||||||
|
withval=$with_xtest;
|
||||||
|
if test "$withval" = yes; then
|
||||||
|
wx_cv_use_xtest='wxUSE_XTEST=yes'
|
||||||
|
else
|
||||||
|
wx_cv_use_xtest='wxUSE_XTEST=no'
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
wx_cv_use_xtest='wxUSE_XTEST=${'DEFAULT_wxUSE_XTEST":-$defaultval}"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
eval "$wx_cv_use_xtest"
|
||||||
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -33666,9 +33703,109 @@ if test "$wxUSE_MOUSEWHEEL" = "yes" ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
||||||
$as_echo "#define wxUSE_UIACTIONSIMULATOR 1" >>confdefs.h
|
if test "$wxUSE_GTK" = 1 -o "$wxUSE_MOTIF" = 1 -o "$wxUSE_X11" = 1; then
|
||||||
|
if test "$wxUSE_XTEST" = "yes" ; then
|
||||||
|
|
||||||
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
|
pkg_failed=no
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XTST" >&5
|
||||||
|
$as_echo_n "checking for XTST... " >&6; }
|
||||||
|
|
||||||
|
if test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$XTST_CFLAGS"; then
|
||||||
|
pkg_cv_XTST_CFLAGS="$XTST_CFLAGS"
|
||||||
|
else
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xtst\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "xtst") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_XTST_CFLAGS=`$PKG_CONFIG --cflags "xtst" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
if test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$XTST_LIBS"; then
|
||||||
|
pkg_cv_XTST_LIBS="$XTST_LIBS"
|
||||||
|
else
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"xtst\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "xtst") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_XTST_LIBS=`$PKG_CONFIG --libs "xtst" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test $pkg_failed = yes; then
|
||||||
|
|
||||||
|
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||||
|
_pkg_short_errors_supported=yes
|
||||||
|
else
|
||||||
|
_pkg_short_errors_supported=no
|
||||||
|
fi
|
||||||
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
|
XTST_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "xtst"`
|
||||||
|
else
|
||||||
|
XTST_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "xtst"`
|
||||||
|
fi
|
||||||
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
echo "$XTST_PKG_ERRORS" >&5
|
||||||
|
|
||||||
|
|
||||||
|
if test "$WXGTK3" = 1; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: XTest not found, disabling wxUIActionSimulator" >&5
|
||||||
|
$as_echo "$as_me: WARNING: XTest not found, disabling wxUIActionSimulator" >&2;}
|
||||||
|
wxUSE_UIACTIONSIMULATOR=no
|
||||||
|
fi
|
||||||
|
wxUSE_XTEST="no"
|
||||||
|
|
||||||
|
|
||||||
|
elif test $pkg_failed = untried; then
|
||||||
|
|
||||||
|
if test "$WXGTK3" = 1; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: XTest not found, disabling wxUIActionSimulator" >&5
|
||||||
|
$as_echo "$as_me: WARNING: XTest not found, disabling wxUIActionSimulator" >&2;}
|
||||||
|
wxUSE_UIACTIONSIMULATOR=no
|
||||||
|
fi
|
||||||
|
wxUSE_XTEST="no"
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
XTST_CFLAGS=$pkg_cv_XTST_CFLAGS
|
||||||
|
XTST_LIBS=$pkg_cv_XTST_LIBS
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
|
||||||
|
GUI_TK_LIBRARY="$GUI_TK_LIBRARY $XTST_LIBS"
|
||||||
|
CFLAGS="$XTST_CFLAGS $CFLAGS"
|
||||||
|
CXXFLAGS="$XTST_CFLAGS $CXXFLAGS"
|
||||||
|
$as_echo "#define wxUSE_XTEST 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
elif test "$WXGTK3" = 1; then
|
||||||
|
wxUSE_UIACTIONSIMULATOR=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
||||||
|
$as_echo "#define wxUSE_UIACTIONSIMULATOR 1" >>confdefs.h
|
||||||
|
|
||||||
|
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
|
if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
|
||||||
|
35
configure.in
35
configure.in
@@ -542,6 +542,7 @@ WX_ARG_WITHOUT(gtkprint, [ --without-gtkprint don't use GTK printing sup
|
|||||||
WX_ARG_WITH(gnomevfs, [ --with-gnomevfs use GNOME VFS for associating MIME types], wxUSE_LIBGNOMEVFS)
|
WX_ARG_WITH(gnomevfs, [ --with-gnomevfs use GNOME VFS for associating MIME types], wxUSE_LIBGNOMEVFS)
|
||||||
WX_ARG_WITH(libnotify, [ --with-libnotify use libnotify for notifications], wxUSE_LIBNOTIFY)
|
WX_ARG_WITH(libnotify, [ --with-libnotify use libnotify for notifications], wxUSE_LIBNOTIFY)
|
||||||
WX_ARG_WITH(opengl, [ --with-opengl use OpenGL (or Mesa)], wxUSE_OPENGL)
|
WX_ARG_WITH(opengl, [ --with-opengl use OpenGL (or Mesa)], wxUSE_OPENGL)
|
||||||
|
WX_ARG_WITH(xtest, [ --with-xtest use XTest extension], wxUSE_XTEST)
|
||||||
|
|
||||||
fi
|
fi
|
||||||
dnl for GUI only
|
dnl for GUI only
|
||||||
@@ -6389,8 +6390,38 @@ if test "$wxUSE_MOUSEWHEEL" = "yes" ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
||||||
AC_DEFINE(wxUSE_UIACTIONSIMULATOR)
|
if test "$wxUSE_GTK" = 1 -o "$wxUSE_MOTIF" = 1 -o "$wxUSE_X11" = 1; then
|
||||||
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
|
if test "$wxUSE_XTEST" = "yes" ; then
|
||||||
|
PKG_CHECK_MODULES(XTST, xtst,
|
||||||
|
[
|
||||||
|
GUI_TK_LIBRARY="$GUI_TK_LIBRARY $XTST_LIBS"
|
||||||
|
CFLAGS="$XTST_CFLAGS $CFLAGS"
|
||||||
|
CXXFLAGS="$XTST_CFLAGS $CXXFLAGS"
|
||||||
|
AC_DEFINE(wxUSE_XTEST)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
if test "$WXGTK3" = 1; then
|
||||||
|
dnl This class can't work without XTest with GTK+ 3
|
||||||
|
dnl which uses XInput2 and so ignores XSendEvent().
|
||||||
|
AC_MSG_WARN([XTest not found, disabling wxUIActionSimulator])
|
||||||
|
wxUSE_UIACTIONSIMULATOR=no
|
||||||
|
fi
|
||||||
|
dnl The other ports can use XSendEvent(), so don't warn
|
||||||
|
wxUSE_XTEST="no"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
elif test "$WXGTK3" = 1; then
|
||||||
|
dnl As per above, wxUIActionSimulator can't be used in this case,
|
||||||
|
dnl but there is no need to warn, presumably the user knows what
|
||||||
|
dnl he's doing if --without-xtest was explicitly specified.
|
||||||
|
wxUSE_UIACTIONSIMULATOR=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
|
||||||
|
AC_DEFINE(wxUSE_UIACTIONSIMULATOR)
|
||||||
|
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
|
if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
|
||||||
|
@@ -88,6 +88,7 @@ All (GUI):
|
|||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
- Make wxUIActionSimulator work with GTK+ 3 (Scott Talbert).
|
||||||
- Implement setting link colours in wxHyperlinkCtrl for GTK+3 (Hanmac).
|
- Implement setting link colours in wxHyperlinkCtrl for GTK+3 (Hanmac).
|
||||||
- Support background colour in wxDataViewCtrl attributes.
|
- Support background colour in wxDataViewCtrl attributes.
|
||||||
- Improve wxSpinCtrl best size calculation.
|
- Improve wxSpinCtrl best size calculation.
|
||||||
|
@@ -267,6 +267,7 @@ library:
|
|||||||
@itemdef{wxUSE_LIBSDL, Use SDL for wxSound implementation.}
|
@itemdef{wxUSE_LIBSDL, Use SDL for wxSound implementation.}
|
||||||
@itemdef{wxUSE_PLUGINS, See also wxUSE_LIBSDL.}
|
@itemdef{wxUSE_PLUGINS, See also wxUSE_LIBSDL.}
|
||||||
@itemdef{wxUSE_UNIX, Enabled on Unix Platform.}
|
@itemdef{wxUSE_UNIX, Enabled on Unix Platform.}
|
||||||
|
@itemdef(wxUSE_XTEST, Use XTest extension.}
|
||||||
@endDefList
|
@endDefList
|
||||||
|
|
||||||
|
|
||||||
|
44
include/wx/private/uiaction.h
Normal file
44
include/wx/private/uiaction.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/private/uiaction.h
|
||||||
|
// Purpose: wxUIActionSimulatorImpl declaration
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2016-05-21
|
||||||
|
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_PRIVATE_UIACTION_H_
|
||||||
|
#define _WX_PRIVATE_UIACTION_H_
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Platform-specific implementation of wxUIActionSimulator
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxUIActionSimulatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxUIActionSimulatorImpl() { }
|
||||||
|
virtual ~wxUIActionSimulatorImpl() { }
|
||||||
|
|
||||||
|
// Low level mouse methods which must be implemented in the derived class.
|
||||||
|
virtual bool MouseMove(long x, long y) = 0;
|
||||||
|
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) = 0;
|
||||||
|
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) = 0;
|
||||||
|
|
||||||
|
// Higher level mouse methods which have default implementation in the base
|
||||||
|
// class but can be overridden if necessary.
|
||||||
|
virtual bool MouseClick(int button = wxMOUSE_BTN_LEFT);
|
||||||
|
virtual bool MouseDblClick(int button = wxMOUSE_BTN_LEFT);
|
||||||
|
virtual bool MouseDragDrop(long x1, long y1, long x2, long y2,
|
||||||
|
int button = wxMOUSE_BTN_LEFT);
|
||||||
|
|
||||||
|
// The low-level port-specific function which really generates the key
|
||||||
|
// presses. It should generate exactly one key event with the given
|
||||||
|
// parameters.
|
||||||
|
virtual bool DoKey(int keycode, int modifiers, bool isDown) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WX_PRIVATE_UIACTION_H_
|
@@ -2,11 +2,10 @@
|
|||||||
// Name: wx/uiaction.h
|
// Name: wx/uiaction.h
|
||||||
// Purpose: wxUIActionSimulator interface
|
// Purpose: wxUIActionSimulator interface
|
||||||
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
||||||
// Modified by:
|
|
||||||
// Created: 2010-03-06
|
// Created: 2010-03-06
|
||||||
// Copyright: (c) Kevin Ollivier
|
// Copyright: (c) 2010 Kevin Ollivier
|
||||||
// (c) 2010 Steven Lamerton
|
// (c) 2010 Steven Lamerton
|
||||||
// (c) 2010 Vadim Zeitlin
|
// (c) 2010-2016 Vadim Zeitlin
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -22,11 +21,8 @@
|
|||||||
class WXDLLIMPEXP_CORE wxUIActionSimulator
|
class WXDLLIMPEXP_CORE wxUIActionSimulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxUIActionSimulator() { }
|
wxUIActionSimulator();
|
||||||
|
~wxUIActionSimulator();
|
||||||
|
|
||||||
// Default dtor, copy ctor and assignment operator are ok (even though the
|
|
||||||
// last two don't make much sense for this class).
|
|
||||||
|
|
||||||
|
|
||||||
// Mouse simulation
|
// Mouse simulation
|
||||||
@@ -82,10 +78,12 @@ private:
|
|||||||
void SimulateModifiers(int modifier, bool isDown);
|
void SimulateModifiers(int modifier, bool isDown);
|
||||||
|
|
||||||
|
|
||||||
// The low-level port-specific function which really generates the key
|
|
||||||
// presses. It should generate exactly one key event with the given
|
// This pointer is allocated in the ctor and points to the
|
||||||
// parameters.
|
// platform-specific implementation.
|
||||||
bool DoKey(int keycode, int modifiers, bool isDown);
|
class wxUIActionSimulatorImpl* const m_impl;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulator);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_UIACTIONSIMULATOR
|
#endif // wxUSE_UIACTIONSIMULATOR
|
||||||
|
@@ -41,3 +41,11 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif /* wxUSE_GSTREAMER */
|
#endif /* wxUSE_GSTREAMER */
|
||||||
|
|
||||||
|
#ifndef wxUSE_XTEST
|
||||||
|
# ifdef wxABORT_ON_CONFIG_ERROR
|
||||||
|
# error "wxUSE_XTEST must be defined, please read comment near the top of this file."
|
||||||
|
# else
|
||||||
|
# define wxUSE_XTEST 0
|
||||||
|
# endif
|
||||||
|
#endif /* !defined(wxUSE_XTEST) */
|
||||||
|
@@ -67,6 +67,13 @@ public:
|
|||||||
wxX11Display() { m_dpy = XOpenDisplay(NULL); }
|
wxX11Display() { m_dpy = XOpenDisplay(NULL); }
|
||||||
~wxX11Display() { if ( m_dpy ) XCloseDisplay(m_dpy); }
|
~wxX11Display() { if ( m_dpy ) XCloseDisplay(m_dpy); }
|
||||||
|
|
||||||
|
// Pseudo move ctor: steals the open display from the other object.
|
||||||
|
explicit wxX11Display(wxX11Display& display)
|
||||||
|
{
|
||||||
|
m_dpy = display.m_dpy;
|
||||||
|
display.m_dpy = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
operator Display *() const { return m_dpy; }
|
operator Display *() const { return m_dpy; }
|
||||||
|
|
||||||
// Using DefaultRootWindow() with an object of wxX11Display class doesn't
|
// Using DefaultRootWindow() with an object of wxX11Display class doesn't
|
||||||
|
@@ -2,9 +2,9 @@
|
|||||||
// Name: uiaction.cpp
|
// Name: uiaction.cpp
|
||||||
// Purpose: wxUIActionSimulator sample
|
// Purpose: wxUIActionSimulator sample
|
||||||
// Author: Kevin Ollivier
|
// Author: Kevin Ollivier
|
||||||
// Modified by:
|
|
||||||
// Created: 04/01/98
|
// Created: 04/01/98
|
||||||
// Copyright: (c) Kevin Ollivier, Steven Lamerton
|
// Copyright: (c) 2010 Kevin Ollivier, Steven Lamerton
|
||||||
|
// (c) 2016 Vadim Zeitlin
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
#include "wx/uiaction.h"
|
#include "wx/uiaction.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/stopwatch.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// resources
|
// resources
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -76,6 +78,7 @@ public:
|
|||||||
MyFrame(const wxString& title);
|
MyFrame(const wxString& title);
|
||||||
|
|
||||||
void OnButtonPressed(wxCommandEvent& event);
|
void OnButtonPressed(wxCommandEvent& event);
|
||||||
|
void OnNew(wxCommandEvent& event);
|
||||||
void OnRunSimulation(wxCommandEvent& event);
|
void OnRunSimulation(wxCommandEvent& event);
|
||||||
void OnSimulateText(wxCommandEvent& event);
|
void OnSimulateText(wxCommandEvent& event);
|
||||||
void OnExit(wxCommandEvent& WXUNUSED(event)) { Close(); }
|
void OnExit(wxCommandEvent& WXUNUSED(event)) { Close(); }
|
||||||
@@ -89,6 +92,7 @@ private:
|
|||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_BUTTON(wxID_ANY, MyFrame::OnButtonPressed)
|
EVT_BUTTON(wxID_ANY, MyFrame::OnButtonPressed)
|
||||||
|
EVT_MENU(wxID_NEW, MyFrame::OnNew)
|
||||||
EVT_MENU(RunSimulation, MyFrame::OnRunSimulation)
|
EVT_MENU(RunSimulation, MyFrame::OnRunSimulation)
|
||||||
EVT_MENU(SimulateText, MyFrame::OnSimulateText)
|
EVT_MENU(SimulateText, MyFrame::OnSimulateText)
|
||||||
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
|
||||||
@@ -139,9 +143,9 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
wxMenu *fileMenu = new wxMenu;
|
wxMenu *fileMenu = new wxMenu;
|
||||||
|
|
||||||
fileMenu->Append(wxID_NEW, "&New File...", "Open a new file");
|
fileMenu->Append(wxID_NEW, "&New File...", "Open a new file");
|
||||||
fileMenu->Append(RunSimulation, "&Run Simulation",
|
fileMenu->Append(RunSimulation, "&Run Simulation\tCtrl-R",
|
||||||
"Run predefined UI action simulation");
|
"Run predefined UI action simulation");
|
||||||
fileMenu->Append(SimulateText, "Simulate &text input...",
|
fileMenu->Append(SimulateText, "Simulate &text input...\tCtrl-T",
|
||||||
"Enter text to simulate");
|
"Enter text to simulate");
|
||||||
fileMenu->AppendSeparator();
|
fileMenu->AppendSeparator();
|
||||||
|
|
||||||
@@ -170,8 +174,25 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
|
|
||||||
|
void MyFrame::OnNew(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
m_text->AppendText("\"New\" menu item was selected\n");
|
||||||
|
}
|
||||||
|
|
||||||
void MyFrame::OnRunSimulation(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnRunSimulation(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
|
m_text->SetValue("=== Starting the simulation "
|
||||||
|
"(release any pressed keys) ===\n");
|
||||||
|
|
||||||
|
// This sleep is needed to give the time for the currently pressed modifier
|
||||||
|
// keys, if any, to be released. Notice that Control modifier could well be
|
||||||
|
// pressed if this command was activated from the menu using accelerator
|
||||||
|
// and keeping it pressed would totally derail the test below, e.g. "A" key
|
||||||
|
// press would actually become "Ctrl+A" selecting the entire text and so on.
|
||||||
|
wxMilliSleep(500);
|
||||||
|
|
||||||
|
wxStopWatch sw;
|
||||||
|
|
||||||
wxUIActionSimulator sim;
|
wxUIActionSimulator sim;
|
||||||
|
|
||||||
// Add some extra distance to take account of window decorations
|
// Add some extra distance to take account of window decorations
|
||||||
@@ -193,6 +214,15 @@ void MyFrame::OnRunSimulation(wxCommandEvent& WXUNUSED(event))
|
|||||||
sim.Text("1 234.57e-8");
|
sim.Text("1 234.57e-8");
|
||||||
sim.Char(WXK_RETURN);
|
sim.Char(WXK_RETURN);
|
||||||
|
|
||||||
|
// Process the resulting text events
|
||||||
|
wxYield();
|
||||||
|
|
||||||
|
// Emulate opening a menu from keyboard.
|
||||||
|
sim.Char('F', wxMOD_ALT);
|
||||||
|
sim.Char('N');
|
||||||
|
wxYield();
|
||||||
|
|
||||||
|
m_text->AppendText(wxString::Format("\n=== Done in %ldms ===\n", sw.Time()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::OnSimulateText(wxCommandEvent& WXUNUSED(event))
|
void MyFrame::OnSimulateText(wxCommandEvent& WXUNUSED(event))
|
||||||
|
10
setup.h.in
10
setup.h.in
@@ -639,6 +639,16 @@
|
|||||||
|
|
||||||
#define wxUSE_GSTREAMER_PLAYER 0
|
#define wxUSE_GSTREAMER_PLAYER 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use XTest extension to implement wxUIActionSimulator?
|
||||||
|
|
||||||
|
Default is 1, it is set to 0 if the necessary headers/libraries are not
|
||||||
|
found by configure.
|
||||||
|
|
||||||
|
Recommended setting: 1, wxUIActionSimulator won't work in wxGTK3 without it.
|
||||||
|
*/
|
||||||
|
#define wxUSE_XTEST 0
|
||||||
|
|
||||||
/* --- start MSW options --- */
|
/* --- start MSW options --- */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2,11 +2,10 @@
|
|||||||
// Name: src/common/uiactioncmn.cpp
|
// Name: src/common/uiactioncmn.cpp
|
||||||
// Purpose: wxUIActionSimulator common implementation
|
// Purpose: wxUIActionSimulator common implementation
|
||||||
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
||||||
// Modified by:
|
|
||||||
// Created: 2010-03-06
|
// Created: 2010-03-06
|
||||||
// Copyright: (c) Kevin Ollivier
|
// Copyright: (c) 2010 Kevin Ollivier
|
||||||
// (c) 2010 Steven Lamerton
|
// (c) 2010 Steven Lamerton
|
||||||
// (c) 2010 Vadim Zeitlin
|
// (c) 2010-2016 Vadim Zeitlin
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -24,8 +23,48 @@
|
|||||||
#include "wx/listbox.h"
|
#include "wx/listbox.h"
|
||||||
#endif // wxNO_RTTI
|
#endif // wxNO_RTTI
|
||||||
|
|
||||||
|
#include "wx/private/uiaction.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Methods forwarded to wxUIActionSimulatorImpl
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxUIActionSimulator::MouseMove(long x, long y)
|
||||||
|
{
|
||||||
|
return m_impl->MouseMove(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulator::MouseDown(int button)
|
||||||
|
{
|
||||||
|
return m_impl->MouseDown(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulator::MouseUp(int button)
|
||||||
|
{
|
||||||
|
return m_impl->MouseUp(button);
|
||||||
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseClick(int button)
|
bool wxUIActionSimulator::MouseClick(int button)
|
||||||
|
{
|
||||||
|
return m_impl->MouseClick(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulator::MouseDblClick(int button)
|
||||||
|
{
|
||||||
|
return m_impl->MouseDblClick(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
|
||||||
|
int button)
|
||||||
|
{
|
||||||
|
return m_impl->MouseDragDrop(x1, y1, x2, y2, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Methods implemented in wxUIActionSimulatorImpl itself
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorImpl::MouseClick(int button)
|
||||||
{
|
{
|
||||||
MouseDown(button);
|
MouseDown(button);
|
||||||
MouseUp(button);
|
MouseUp(button);
|
||||||
@@ -33,9 +72,7 @@ bool wxUIActionSimulator::MouseClick(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __WXOSX__
|
bool wxUIActionSimulatorImpl::MouseDblClick(int button)
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDblClick(int button)
|
|
||||||
{
|
{
|
||||||
MouseDown(button);
|
MouseDown(button);
|
||||||
MouseUp(button);
|
MouseUp(button);
|
||||||
@@ -45,7 +82,7 @@ bool wxUIActionSimulator::MouseDblClick(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
|
bool wxUIActionSimulatorImpl::MouseDragDrop(long x1, long y1, long x2, long y2,
|
||||||
int button)
|
int button)
|
||||||
{
|
{
|
||||||
MouseMove(x1, y1);
|
MouseMove(x1, y1);
|
||||||
@@ -56,8 +93,6 @@ bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown)
|
wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown)
|
||||||
{
|
{
|
||||||
@@ -69,7 +104,7 @@ wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown)
|
|||||||
if ( isDown )
|
if ( isDown )
|
||||||
SimulateModifiers(modifiers, true);
|
SimulateModifiers(modifiers, true);
|
||||||
|
|
||||||
bool rc = DoKey(keycode, modifiers, isDown);
|
bool rc = m_impl->DoKey(keycode, modifiers, isDown);
|
||||||
|
|
||||||
if ( !isDown )
|
if ( !isDown )
|
||||||
SimulateModifiers(modifiers, false);
|
SimulateModifiers(modifiers, false);
|
||||||
@@ -80,11 +115,11 @@ wxUIActionSimulator::Key(int keycode, int modifiers, bool isDown)
|
|||||||
void wxUIActionSimulator::SimulateModifiers(int modifiers, bool isDown)
|
void wxUIActionSimulator::SimulateModifiers(int modifiers, bool isDown)
|
||||||
{
|
{
|
||||||
if ( modifiers & wxMOD_SHIFT )
|
if ( modifiers & wxMOD_SHIFT )
|
||||||
DoKey(WXK_SHIFT, modifiers, isDown);
|
m_impl->DoKey(WXK_SHIFT, modifiers, isDown);
|
||||||
if ( modifiers & wxMOD_ALT )
|
if ( modifiers & wxMOD_ALT )
|
||||||
DoKey(WXK_ALT, modifiers, isDown);
|
m_impl->DoKey(WXK_ALT, modifiers, isDown);
|
||||||
if ( modifiers & wxMOD_CONTROL )
|
if ( modifiers & wxMOD_CONTROL )
|
||||||
DoKey(WXK_CONTROL, modifiers, isDown);
|
m_impl->DoKey(WXK_CONTROL, modifiers, isDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::Char(int keycode, int modifiers)
|
bool wxUIActionSimulator::Char(int keycode, int modifiers)
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/uiaction.h"
|
#include "wx/uiaction.h"
|
||||||
|
#include "wx/private/uiaction.h"
|
||||||
|
|
||||||
#include "wx/msw/wrapwin.h"
|
#include "wx/msw/wrapwin.h"
|
||||||
|
|
||||||
#include "wx/msw/private/keyboard.h"
|
#include "wx/msw/private/keyboard.h"
|
||||||
@@ -28,6 +30,31 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class wxUIActionSimulatorMSWImpl : public wxUIActionSimulatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Returns a pointer to the global simulator object: as it's stateless, we
|
||||||
|
// can reuse the same one without having to allocate it on the heap all the
|
||||||
|
// time.
|
||||||
|
static wxUIActionSimulatorMSWImpl* Get()
|
||||||
|
{
|
||||||
|
static wxUIActionSimulatorMSWImpl s_impl;
|
||||||
|
return &s_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class has no public ctors, use Get() instead.
|
||||||
|
wxUIActionSimulatorMSWImpl() { }
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorMSWImpl);
|
||||||
|
};
|
||||||
|
|
||||||
DWORD EventTypeForMouseButton(int button, bool isDown)
|
DWORD EventTypeForMouseButton(int button, bool isDown)
|
||||||
{
|
{
|
||||||
switch (button)
|
switch (button)
|
||||||
@@ -49,7 +76,7 @@ DWORD EventTypeForMouseButton(int button, bool isDown)
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDown(int button)
|
bool wxUIActionSimulatorMSWImpl::MouseDown(int button)
|
||||||
{
|
{
|
||||||
POINT p;
|
POINT p;
|
||||||
wxGetCursorPosMSW(&p);
|
wxGetCursorPosMSW(&p);
|
||||||
@@ -57,7 +84,7 @@ bool wxUIActionSimulator::MouseDown(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseMove(long x, long y)
|
bool wxUIActionSimulatorMSWImpl::MouseMove(long x, long y)
|
||||||
{
|
{
|
||||||
// Because MOUSEEVENTF_ABSOLUTE takes measurements scaled between 0 & 65535
|
// Because MOUSEEVENTF_ABSOLUTE takes measurements scaled between 0 & 65535
|
||||||
// we need to scale our input too
|
// we need to scale our input too
|
||||||
@@ -73,7 +100,7 @@ bool wxUIActionSimulator::MouseMove(long x, long y)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseUp(int button)
|
bool wxUIActionSimulatorMSWImpl::MouseUp(int button)
|
||||||
{
|
{
|
||||||
POINT p;
|
POINT p;
|
||||||
wxGetCursorPosMSW(&p);
|
wxGetCursorPosMSW(&p);
|
||||||
@@ -82,7 +109,7 @@ bool wxUIActionSimulator::MouseUp(int button)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
wxUIActionSimulatorMSWImpl::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
||||||
{
|
{
|
||||||
bool isExtended;
|
bool isExtended;
|
||||||
DWORD vkkeycode = wxMSWKeyboard::WXToVK(keycode, &isExtended);
|
DWORD vkkeycode = wxMSWKeyboard::WXToVK(keycode, &isExtended);
|
||||||
@@ -98,4 +125,15 @@ wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::wxUIActionSimulator()
|
||||||
|
: m_impl(wxUIActionSimulatorMSWImpl::Get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::~wxUIActionSimulator()
|
||||||
|
{
|
||||||
|
// We can use a static wxUIActionSimulatorMSWImpl object because it's
|
||||||
|
// stateless, so no need to delete it.
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_UIACTIONSIMULATOR
|
#endif // wxUSE_UIACTIONSIMULATOR
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: src/osx/uiaction_osx.cpp
|
// Name: src/osx/uiaction_osx.cpp
|
||||||
// Purpose: wxUIActionSimulator implementation
|
// Purpose: wxUIActionSimulatorOSXImpl implementation
|
||||||
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
||||||
// Modified by:
|
// Modified by:
|
||||||
// Created: 2010-03-06
|
// Created: 2010-03-06
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#if wxUSE_UIACTIONSIMULATOR
|
#if wxUSE_UIACTIONSIMULATOR
|
||||||
|
|
||||||
#include "wx/uiaction.h"
|
#include "wx/uiaction.h"
|
||||||
|
#include "wx/private/uiaction.h"
|
||||||
|
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
|
||||||
@@ -111,9 +112,38 @@ CGPoint GetMousePosition()
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class wxUIActionSimulatorOSXImpl : public wxUIActionSimulatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Returns a pointer to the global simulator object: as it's stateless, we
|
||||||
|
// can reuse the same one without having to allocate it on the heap all the
|
||||||
|
// time.
|
||||||
|
static wxUIActionSimulatorOSXImpl* Get()
|
||||||
|
{
|
||||||
|
static wxUIActionSimulatorOSXImpl s_impl;
|
||||||
|
return &s_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual bool MouseDblClick(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
virtual bool MouseDragDrop(long x1, long y1, long x2, long y2,
|
||||||
|
int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class has no public ctors, use Get() instead.
|
||||||
|
wxUIActionSimulatorOSXImpl() { }
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorOSXImpl);
|
||||||
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDown(int button)
|
bool wxUIActionSimulatorOSXImpl::MouseDown(int button)
|
||||||
{
|
{
|
||||||
CGEventType type = CGEventTypeForMouseButton(button, true);
|
CGEventType type = CGEventTypeForMouseButton(button, true);
|
||||||
wxCFRef<CGEventRef> event(
|
wxCFRef<CGEventRef> event(
|
||||||
@@ -131,7 +161,7 @@ bool wxUIActionSimulator::MouseDown(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseMove(long x, long y)
|
bool wxUIActionSimulatorOSXImpl::MouseMove(long x, long y)
|
||||||
{
|
{
|
||||||
CGPoint pos;
|
CGPoint pos;
|
||||||
pos.x = x;
|
pos.x = x;
|
||||||
@@ -154,7 +184,7 @@ bool wxUIActionSimulator::MouseMove(long x, long y)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseUp(int button)
|
bool wxUIActionSimulatorOSXImpl::MouseUp(int button)
|
||||||
{
|
{
|
||||||
CGEventType type = CGEventTypeForMouseButton(button, false);
|
CGEventType type = CGEventTypeForMouseButton(button, false);
|
||||||
wxCFRef<CGEventRef> event(
|
wxCFRef<CGEventRef> event(
|
||||||
@@ -172,7 +202,7 @@ bool wxUIActionSimulator::MouseUp(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDblClick(int button)
|
bool wxUIActionSimulatorOSXImpl::MouseDblClick(int button)
|
||||||
{
|
{
|
||||||
CGEventType downtype = CGEventTypeForMouseButton(button, true);
|
CGEventType downtype = CGEventTypeForMouseButton(button, true);
|
||||||
CGEventType uptype = CGEventTypeForMouseButton(button, false);
|
CGEventType uptype = CGEventTypeForMouseButton(button, false);
|
||||||
@@ -201,7 +231,7 @@ bool wxUIActionSimulator::MouseDblClick(int button)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
|
bool wxUIActionSimulatorOSXImpl::MouseDragDrop(long x1, long y1, long x2, long y2,
|
||||||
int button)
|
int button)
|
||||||
{
|
{
|
||||||
CGPoint pos1,pos2;
|
CGPoint pos1,pos2;
|
||||||
@@ -241,7 +271,7 @@ bool wxUIActionSimulator::MouseDragDrop(long x1, long y1, long x2, long y2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
wxUIActionSimulatorOSXImpl::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
||||||
{
|
{
|
||||||
CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
|
CGKeyCode cgcode = wxCharCodeWXToOSX((wxKeyCode)keycode);
|
||||||
|
|
||||||
@@ -258,5 +288,15 @@ wxUIActionSimulator::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_UIACTIONSIMULATOR
|
wxUIActionSimulator::wxUIActionSimulator()
|
||||||
|
: m_impl(wxUIActionSimulatorOSXImpl::Get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::~wxUIActionSimulator()
|
||||||
|
{
|
||||||
|
// We can use a static wxUIActionSimulatorOSXImpl object because it's
|
||||||
|
// stateless, so no need to delete it.
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_UIACTIONSIMULATOR
|
||||||
|
@@ -12,13 +12,15 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/uiaction.h"
|
||||||
|
#include "wx/private/uiaction.h"
|
||||||
|
|
||||||
#include <QtTest/QtTestGui>
|
#include <QtTest/QtTestGui>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "wx/qt/defs.h"
|
#include "wx/qt/defs.h"
|
||||||
#include "wx/qt/private/utils.h"
|
#include "wx/qt/private/utils.h"
|
||||||
#include "wx/uiaction.h"
|
|
||||||
#include "wx/qt/private/converter.h"
|
#include "wx/qt/private/converter.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -37,6 +39,31 @@ inline QWindow* argForEvents(QWidget* w) { return w->windowHandle(); }
|
|||||||
inline QWidget* argForEvents(QWidget* w) { return w; }
|
inline QWidget* argForEvents(QWidget* w) { return w; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class wxUIActionSimulatorQtImpl : public wxUIActionSimulatorImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Returns a pointer to the global simulator object: as it's stateless, we
|
||||||
|
// can reuse the same one without having to allocate it on the heap all the
|
||||||
|
// time.
|
||||||
|
static wxUIActionSimulatorQtImpl* Get()
|
||||||
|
{
|
||||||
|
static wxUIActionSimulatorQtImpl s_impl;
|
||||||
|
return &s_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class has no public ctors, use Get() instead.
|
||||||
|
wxUIActionSimulatorQtImpl() { }
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorQtImpl);
|
||||||
|
};
|
||||||
|
|
||||||
static MouseButton ConvertMouseButton( int button )
|
static MouseButton ConvertMouseButton( int button )
|
||||||
{
|
{
|
||||||
MouseButton qtButton;
|
MouseButton qtButton;
|
||||||
@@ -95,24 +122,24 @@ static bool SimulateKeyboardKey( KeyAction keyAction, Key key )
|
|||||||
return widget != NULL;
|
return widget != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDown( int button )
|
bool wxUIActionSimulatorQtImpl::MouseDown( int button )
|
||||||
{
|
{
|
||||||
return SimulateMouseButton( MousePress, ConvertMouseButton( button ));
|
return SimulateMouseButton( MousePress, ConvertMouseButton( button ));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseUp(int button)
|
bool wxUIActionSimulatorQtImpl::MouseUp(int button)
|
||||||
{
|
{
|
||||||
return SimulateMouseButton( MouseRelease, ConvertMouseButton( button ));
|
return SimulateMouseButton( MouseRelease, ConvertMouseButton( button ));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseMove(long x, long y)
|
bool wxUIActionSimulatorQtImpl::MouseMove(long x, long y)
|
||||||
{
|
{
|
||||||
QCursor::setPos( x, y );
|
QCursor::setPos( x, y );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::DoKey(int keyCode, int modifiers, bool isDown)
|
bool wxUIActionSimulatorQtImpl::DoKey(int keyCode, int modifiers, bool isDown)
|
||||||
{
|
{
|
||||||
Qt::KeyboardModifiers qtmodifiers;
|
Qt::KeyboardModifiers qtmodifiers;
|
||||||
enum Key key;
|
enum Key key;
|
||||||
@@ -124,5 +151,16 @@ bool wxUIActionSimulator::DoKey(int keyCode, int modifiers, bool isDown)
|
|||||||
return SimulateKeyboardKey( keyAction, key );
|
return SimulateKeyboardKey( keyAction, key );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_UIACTIONSIMULATOR
|
|
||||||
|
|
||||||
|
wxUIActionSimulator::wxUIActionSimulator()
|
||||||
|
: m_impl(wxUIActionSimulatorQtImpl::Get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::~wxUIActionSimulator()
|
||||||
|
{
|
||||||
|
// We can use a static wxUIActionSimulatorQtImpl object because it's
|
||||||
|
// stateless, so no need to delete it.
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_UIACTIONSIMULATOR
|
||||||
|
@@ -2,11 +2,10 @@
|
|||||||
// Name: src/unix/uiactionx11.cpp
|
// Name: src/unix/uiactionx11.cpp
|
||||||
// Purpose: wxUIActionSimulator implementation
|
// Purpose: wxUIActionSimulator implementation
|
||||||
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
|
||||||
// Modified by:
|
|
||||||
// Created: 2010-03-06
|
// Created: 2010-03-06
|
||||||
// Copyright: (c) Kevin Ollivier
|
// Copyright: (c) 2010 Kevin Ollivier
|
||||||
// (c) 2010 Steven Lamerton
|
// (c) 2010 Steven Lamerton
|
||||||
// (c) 2010 Vadim Zeitlin
|
// (c) 2010-2016 Vadim Zeitlin
|
||||||
// Licence: wxWindows licence
|
// Licence: wxWindows licence
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -18,16 +17,72 @@
|
|||||||
#include "wx/event.h"
|
#include "wx/event.h"
|
||||||
#include "wx/evtloop.h"
|
#include "wx/evtloop.h"
|
||||||
|
|
||||||
|
#include "wx/private/uiaction.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#if wxUSE_XTEST
|
||||||
|
#include <X11/extensions/XTest.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "wx/unix/utilsx11.h"
|
#include "wx/unix/utilsx11.h"
|
||||||
|
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Normally we fall back on "plain X" implementation if XTest is not available,
|
||||||
|
// but it's useless to do it when using GTK+ 3 as it's not going to work with
|
||||||
|
// it anyhow because GTK+ 3 needs XInput2 events and not the "classic" ones we
|
||||||
|
// synthesize here, so don't even compile in this code for wxGTK3 port.
|
||||||
|
#define wxUSE_PLAINX_IMPL (!defined(__WXGTK3__))
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
void SendButtonEvent(int button, bool isDown)
|
// Base class for both available X11 implementations.
|
||||||
|
class wxUIActionSimulatorX11Impl : public wxUIActionSimulatorImpl
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
// Return the most appopriate implementation to use: if XTest is available,
|
||||||
|
// use it, otherwise use plain X11 calls.
|
||||||
|
//
|
||||||
|
// The returned pointer is owned by the caller.
|
||||||
|
static wxUIActionSimulatorImpl* New();
|
||||||
|
|
||||||
|
virtual bool MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// This ctor takes ownership of the display.
|
||||||
|
explicit wxUIActionSimulatorX11Impl(wxX11Display& display)
|
||||||
|
: m_display(display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxX11Display m_display;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Common implementation of Mouse{Down,Up}() which just forwards to
|
||||||
|
// DoX11Button() after translating wx button to X button constant.
|
||||||
|
bool SendButtonEvent(int button, bool isDown);
|
||||||
|
|
||||||
|
virtual bool DoX11Button(int xbutton, bool isDown) = 0;
|
||||||
|
virtual bool DoX11MouseMove(long x, long y) = 0;
|
||||||
|
virtual bool DoX11Key(KeyCode xkeycode, int modifiers, bool isDown) = 0;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorX11Impl);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorX11Impl::SendButtonEvent(int button, bool isDown)
|
||||||
|
{
|
||||||
|
if ( !m_display )
|
||||||
|
return false;
|
||||||
|
|
||||||
int xbutton;
|
int xbutton;
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
@@ -42,12 +97,37 @@ void SendButtonEvent(int button, bool isDown)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG("Unsupported button passed in.");
|
wxFAIL_MSG("Unsupported button passed in.");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxX11Display display;
|
// Ensure that the event is received by the correct window by processing
|
||||||
wxCHECK_RET(display, "No display available!");
|
// all pending events, notably mouse moves.
|
||||||
|
XSync(m_display, False /* don't discard */);
|
||||||
|
|
||||||
|
return DoX11Button(xbutton, isDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_PLAINX_IMPL
|
||||||
|
|
||||||
|
// Implementation using just plain X11 calls.
|
||||||
|
class wxUIActionSimulatorPlainX11Impl : public wxUIActionSimulatorX11Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit wxUIActionSimulatorPlainX11Impl(wxX11Display& display)
|
||||||
|
: wxUIActionSimulatorX11Impl(display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool DoX11Button(int xbutton, bool isDown) wxOVERRIDE;
|
||||||
|
virtual bool DoX11MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool DoX11Key(KeyCode xkeycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorPlainX11Impl);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorPlainX11Impl::DoX11Button(int xbutton, bool isDown)
|
||||||
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
memset(&event, 0x00, sizeof(event));
|
memset(&event, 0x00, sizeof(event));
|
||||||
|
|
||||||
@@ -55,7 +135,7 @@ void SendButtonEvent(int button, bool isDown)
|
|||||||
event.xbutton.button = xbutton;
|
event.xbutton.button = xbutton;
|
||||||
event.xbutton.same_screen = True;
|
event.xbutton.same_screen = True;
|
||||||
|
|
||||||
XQueryPointer(display, display.DefaultRoot(),
|
XQueryPointer(m_display, m_display.DefaultRoot(),
|
||||||
&event.xbutton.root, &event.xbutton.window,
|
&event.xbutton.root, &event.xbutton.window,
|
||||||
&event.xbutton.x_root, &event.xbutton.y_root,
|
&event.xbutton.x_root, &event.xbutton.y_root,
|
||||||
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
||||||
@@ -64,54 +144,29 @@ void SendButtonEvent(int button, bool isDown)
|
|||||||
while (event.xbutton.subwindow)
|
while (event.xbutton.subwindow)
|
||||||
{
|
{
|
||||||
event.xbutton.window = event.xbutton.subwindow;
|
event.xbutton.window = event.xbutton.subwindow;
|
||||||
XQueryPointer(display, event.xbutton.window,
|
XQueryPointer(m_display, event.xbutton.window,
|
||||||
&event.xbutton.root, &event.xbutton.subwindow,
|
&event.xbutton.root, &event.xbutton.subwindow,
|
||||||
&event.xbutton.x_root, &event.xbutton.y_root,
|
&event.xbutton.x_root, &event.xbutton.y_root,
|
||||||
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
XSendEvent(display, PointerWindow, True, 0xfff, &event);
|
XSendEvent(m_display, PointerWindow, True, 0xfff, &event);
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseDown(int button)
|
|
||||||
{
|
|
||||||
SendButtonEvent(button, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseMove(long x, long y)
|
|
||||||
{
|
|
||||||
wxX11Display display;
|
|
||||||
wxASSERT_MSG(display, "No display available!");
|
|
||||||
|
|
||||||
Window root = display.DefaultRoot();
|
|
||||||
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
|
|
||||||
|
|
||||||
// At least with wxGTK we must always process the pending events before the
|
|
||||||
// mouse position change really takes effect, so just do it from here
|
|
||||||
// instead of forcing the client code using this function to always use
|
|
||||||
// wxYield() which is unnecessary under the other platforms.
|
|
||||||
if ( wxEventLoopBase* const loop = wxEventLoop::GetActive() )
|
|
||||||
{
|
|
||||||
loop->YieldFor(wxEVT_CATEGORY_USER_INPUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::MouseUp(int button)
|
bool wxUIActionSimulatorPlainX11Impl::DoX11MouseMove(long x, long y)
|
||||||
{
|
{
|
||||||
SendButtonEvent(button, false);
|
Window root = m_display.DefaultRoot();
|
||||||
|
XWarpPointer(m_display, None, root, 0, 0, 0, 0, x, y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
|
bool
|
||||||
|
wxUIActionSimulatorPlainX11Impl::DoX11Key(KeyCode xkeycode,
|
||||||
|
int modifiers,
|
||||||
|
bool isDown)
|
||||||
{
|
{
|
||||||
wxX11Display display;
|
|
||||||
wxCHECK_MSG(display, false, "No display available!");
|
|
||||||
|
|
||||||
int mask, type;
|
int mask, type;
|
||||||
|
|
||||||
if ( isDown )
|
if ( isDown )
|
||||||
@@ -125,14 +180,9 @@ bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
|
|||||||
mask = KeyReleaseMask;
|
mask = KeyReleaseMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXKeySym xkeysym = wxCharCodeWXToX(keycode);
|
|
||||||
KeyCode xkeycode = XKeysymToKeycode(display, xkeysym);
|
|
||||||
if ( xkeycode == NoSymbol )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Window focus;
|
Window focus;
|
||||||
int revert;
|
int revert;
|
||||||
XGetInputFocus(display, &focus, &revert);
|
XGetInputFocus(m_display, &focus, &revert);
|
||||||
if (focus == None)
|
if (focus == None)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -147,7 +197,7 @@ bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
|
|||||||
mod |= ControlMask;
|
mod |= ControlMask;
|
||||||
|
|
||||||
XKeyEvent event;
|
XKeyEvent event;
|
||||||
event.display = display;
|
event.display = m_display;
|
||||||
event.window = focus;
|
event.window = focus;
|
||||||
event.root = DefaultRootWindow(event.display);
|
event.root = DefaultRootWindow(event.display);
|
||||||
event.subwindow = None;
|
event.subwindow = None;
|
||||||
@@ -166,4 +216,141 @@ bool wxUIActionSimulator::DoKey(int keycode, int modifiers, bool isDown)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_PLAINX_IMPL
|
||||||
|
|
||||||
|
#if wxUSE_XTEST
|
||||||
|
|
||||||
|
// Implementation using XTest extension.
|
||||||
|
class wxUIActionSimulatorXTestImpl : public wxUIActionSimulatorX11Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit wxUIActionSimulatorXTestImpl(wxX11Display& display)
|
||||||
|
: wxUIActionSimulatorX11Impl(display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool DoX11Button(int xbutton, bool isDown) wxOVERRIDE;
|
||||||
|
virtual bool DoX11MouseMove(long x, long y) wxOVERRIDE;
|
||||||
|
virtual bool DoX11Key(KeyCode xkeycode, int modifiers, bool isDown) wxOVERRIDE;
|
||||||
|
|
||||||
|
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorXTestImpl);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorXTestImpl::DoX11Button(int xbutton, bool isDown)
|
||||||
|
{
|
||||||
|
return XTestFakeButtonEvent(m_display, xbutton, isDown, 0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorXTestImpl::DoX11MouseMove(long x, long y)
|
||||||
|
{
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
// We need to take into account the scaling factor as the input coordinates
|
||||||
|
// are in GTK logical "application pixels", while we need the physical
|
||||||
|
// "device pixels" for the X call below, so scale them if we have the
|
||||||
|
// required support at both compile- and run-time.
|
||||||
|
#if GTK_CHECK_VERSION(3,10,0)
|
||||||
|
if ( gtk_check_version(3, 10, 0) == NULL )
|
||||||
|
{
|
||||||
|
if ( GdkScreen* const screen = gdk_screen_get_default() )
|
||||||
|
{
|
||||||
|
// For multi-monitor support we would need to determine to which
|
||||||
|
// monitor the point (x, y) belongs, for now just use the scale
|
||||||
|
// factor of the main one.
|
||||||
|
gint const scale = gdk_screen_get_monitor_scale_factor(screen, 0);
|
||||||
|
x *= scale;
|
||||||
|
y *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // GTK+ 3.10+
|
||||||
|
#endif // __WXGTK3__
|
||||||
|
|
||||||
|
return XTestFakeMotionEvent(m_display, -1, x, y, 0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wxUIActionSimulatorXTestImpl::DoX11Key(KeyCode xkeycode,
|
||||||
|
int WXUNUSED(modifiers),
|
||||||
|
bool isDown)
|
||||||
|
{
|
||||||
|
return XTestFakeKeyEvent(m_display, xkeycode, isDown, 0) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_XTEST
|
||||||
|
|
||||||
|
wxUIActionSimulatorImpl* wxUIActionSimulatorX11Impl::New()
|
||||||
|
{
|
||||||
|
wxX11Display display;
|
||||||
|
|
||||||
|
#if wxUSE_XTEST
|
||||||
|
// If we can fall back on plain X implementation, check if XTest extension
|
||||||
|
// is available and if it isn't, use the other one. OTOH if we don't have
|
||||||
|
// the other one anyhow, then testing for XTest availability is useless.
|
||||||
|
#if wxUSE_PLAINX_IMPL
|
||||||
|
int dummy;
|
||||||
|
if ( XTestQueryExtension(display, &dummy, &dummy, &dummy, &dummy) )
|
||||||
|
#endif // wxUSE_PLAINX_IMPL
|
||||||
|
return new wxUIActionSimulatorXTestImpl(display);
|
||||||
|
#endif // wxUSE_XTEST
|
||||||
|
|
||||||
|
#if wxUSE_PLAINX_IMPL
|
||||||
|
return new wxUIActionSimulatorPlainX11Impl(display);
|
||||||
|
#endif // wxUSE_PLAINX_IMPL
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorX11Impl::MouseDown(int button)
|
||||||
|
{
|
||||||
|
return SendButtonEvent(button, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorX11Impl::MouseMove(long x, long y)
|
||||||
|
{
|
||||||
|
if ( !m_display )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !DoX11MouseMove(x, y) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// At least with wxGTK we must always process the pending events before the
|
||||||
|
// mouse position change really takes effect, so just do it from here
|
||||||
|
// instead of forcing the client code using this function to always use
|
||||||
|
// wxYield() which is unnecessary under the other platforms.
|
||||||
|
if ( wxEventLoopBase* const loop = wxEventLoop::GetActive() )
|
||||||
|
{
|
||||||
|
loop->YieldFor(wxEVT_CATEGORY_USER_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorX11Impl::MouseUp(int button)
|
||||||
|
{
|
||||||
|
return SendButtonEvent(button, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxUIActionSimulatorX11Impl::DoKey(int keycode, int modifiers, bool isDown)
|
||||||
|
{
|
||||||
|
if ( !m_display )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WXKeySym xkeysym = wxCharCodeWXToX(keycode);
|
||||||
|
KeyCode xkeycode = XKeysymToKeycode(m_display, xkeysym);
|
||||||
|
if ( xkeycode == NoSymbol )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return DoX11Key(xkeycode, modifiers, isDown);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::wxUIActionSimulator()
|
||||||
|
: m_impl(wxUIActionSimulatorX11Impl::New())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxUIActionSimulator::~wxUIActionSimulator()
|
||||||
|
{
|
||||||
|
delete m_impl;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_UIACTIONSIMULATOR
|
#endif // wxUSE_UIACTIONSIMULATOR
|
||||||
|
Reference in New Issue
Block a user