Merge branch 'master' into webview-chromium

Merge the changes required by wxWebViewChromium, notably support for the
entry hooks and new wxDynamicLibrary::ListLoaded() Unix implementation.
This commit is contained in:
Vadim Zeitlin 2023-09-06 02:50:51 +02:00
commit 6762d5eaa5
79 changed files with 438 additions and 334 deletions

View file

@ -565,6 +565,7 @@ check_symbol_exists(dlopen dlfcn.h HAVE_DLOPEN)
cmake_pop_check_state()
if(HAVE_DLOPEN)
check_symbol_exists(dladdr dlfcn.h HAVE_DLADDR)
check_symbol_exists(dl_iterate_phdr link.h HAVE_DL_ITERATE_PHDR)
endif()
if(APPLE)

12
configure vendored
View file

@ -35494,6 +35494,18 @@ fi
fi
done
for ac_func in dl_iterate_phdr
do :
ac_fn_c_check_func "$LINENO" "dl_iterate_phdr" "ac_cv_func_dl_iterate_phdr"
if test "x$ac_cv_func_dl_iterate_phdr" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_DL_ITERATE_PHDR 1
_ACEOF
fi
done

View file

@ -4843,7 +4843,7 @@ else
])
])
dnl check also for dlerror()
dnl check also for some optional functions which we may use
if test "$HAVE_DL_FUNCS" = 1; then
AC_CHECK_FUNCS(dladdr,
AC_DEFINE(HAVE_DLADDR),
@ -4855,6 +4855,8 @@ else
])
]
)
AC_CHECK_FUNCS(dl_iterate_phdr)
fi
fi

View file

@ -108,6 +108,11 @@ Changes in behaviour which may result in build errors
compatible with the previous wxWidgets versions, but now compare values, and
not pointers, in their Index() member function.
- Due to the possibility to construct wxString from std::string_view some
previously valid code, such as "wxstr = {"Hello", 2}", is now ambiguous.
Please use explicit class name, e.g. "wxstr = wxString{"Hello", 2}" to
preserve the previous behaviour.
- Generic wxSearchCtrl doesn't provide methods that make sense only for
multiline text controls any longer, for consistency with the other ports.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

After

Width:  |  Height:  |  Size: 840 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 954 B

After

Width:  |  Height:  |  Size: 780 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 803 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 392 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 677 B

After

Width:  |  Height:  |  Size: 2.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 930 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 866 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 264 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 779 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 669 B

After

Width:  |  Height:  |  Size: 1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 609 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 313 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 306 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 533 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 665 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

After

Width:  |  Height:  |  Size: 997 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 389 B

After

Width:  |  Height:  |  Size: 548 B

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,006 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Before After
Before After

View file

@ -2336,10 +2336,10 @@
#if wxUSE_MEDIACTRL
# if !wxUSE_LONGLONG
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxMediaCtrl requires wxUSE_LONLONG"
# error "wxMediaCtrl requires wxUSE_LONGLONG"
# else
# undef wxUSE_LONLONG
# define wxUSE_LONLONG 1
# undef wxUSE_LONGLONG
# define wxUSE_LONGLONG 1
# endif
# endif
#endif /* wxUSE_MEDIACTRL */
@ -2375,10 +2375,10 @@
# endif
# if !wxUSE_LONGLONG
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxRichTextCtrl requires wxUSE_LONLONG"
# error "wxRichTextCtrl requires wxUSE_LONGLONG"
# else
# undef wxUSE_LONLONG
# define wxUSE_LONLONG 1
# undef wxUSE_LONGLONG
# define wxUSE_LONGLONG 1
# endif
# endif
# if !wxUSE_VARIANT

View file

@ -41,6 +41,8 @@ public:
virtual void SetTitle( const wxString& title) override;
virtual wxString GetTitle() const override;
virtual bool MSWProcessMessage(WXMSG* pMsg) override;
protected:
virtual void DoGetSize(int *width, int *height) const override;
virtual void DoGetClientSize(int *width, int *height) const override;

58
include/wx/private/init.h Normal file
View file

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/init.h
// Purpose: Private initialization-related data.
// Author: Vadim Zeitlin
// Created: 2023-09-02
// Copyright: (c) 2023 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_INIT_H_
#define _WX_PRIVATE_INIT_H_
// ----------------------------------------------------------------------------
// Initialization data contains parameters we get from the OS entry function.
// ----------------------------------------------------------------------------
struct WXDLLIMPEXP_BASE wxInitData
{
wxInitData() = default;
// Get the single global object.
static wxInitData& Get();
// Initialize from ANSI command line arguments.
void Initialize(int argc, char** argv);
// This function is used instead of the dtor because the global object can
// be initialized multiple times.
void Free();
// We always have argc and (Unicode) argv, they're filled by Initialize()
// and argv as well as its elements are owned by us, see Free().
int argc = 0;
wchar_t** argv = nullptr;
#ifdef __WINDOWS__
// Initialize from the implicitly available Unicode command line.
void MSWInitialize();
// This pointer is non-null only if MSWInitialize() was called. In this
// case, argv is also set to it and, because this pointer needs to be freed
// using MSW-specific function, argv must not be freed at all.
//
// It's also possible to use Initialize(), even under Windows, in which
// case this pointer remains null and argv must be freed as usual.
wchar_t** argvMSW = nullptr;
#else // !__WINDOWS__
// Under other platforms we typically need the original, non-Unicode
// command line version, so we keep it too. Unlike argv that we allocate,
// this pointer doesn't need to be freed.
char** argvA = nullptr;
#endif // __WINDOWS__
wxDECLARE_NO_COPY_CLASS(wxInitData);
};
#endif // _WX_PRIVATE_INIT_H_

View file

@ -500,4 +500,17 @@ public:
typedef wxScrolled<wxWindow> wxScrolledCanvas;
namespace wxPrivate
{
// This class is specifically DLL-exported, even though it's trivial, in order
// to ensure that there is only a single copy of wxScrolledCanvas in the wx DLL.
class WXDLLIMPEXP_CORE wxScrolledCanvasDummySubclass : public wxScrolledCanvas
{
public:
wxScrolledCanvasDummySubclass();
};
} // namespace wxPrivate
#endif // _WX_SCROLWIN_H_BASE_

View file

@ -1263,7 +1263,7 @@ public:
#endif
#ifdef wxHAS_STD_STRING_VIEW
wxString(std::wstring_view view)
explicit wxString(std::wstring_view view)
{ assign(view.data(), view.length()); }
#endif // wxHAS_STD_STRING_VIEW
@ -1272,7 +1272,7 @@ public:
{ assign(str.c_str(), str.length()); }
#ifdef wxHAS_STD_STRING_VIEW
wxString(std::string_view view)
explicit wxString(std::string_view view)
{ assign(view.data(), view.length()); }
#endif // wxHAS_STD_STRING_VIEW
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
@ -1883,6 +1883,29 @@ public:
{ return assign(s); }
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
#if wxUSE_UNICODE_WCHAR
wxString& operator=(const std::wstring& str) { m_impl = str; return *this; }
wxString& operator=(std::wstring&& str) noexcept { m_impl = std::move(str); return *this; }
#else // wxUSE_UNICODE_UTF8
wxString& operator=(const std::wstring& str)
{ return assign(str.c_str(), str.length()); }
#endif
#ifdef wxHAS_STD_STRING_VIEW
wxString& operator=(std::wstring_view view)
{ return assign(view.data(), view.length()); }
#endif // wxHAS_STD_STRING_VIEW
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
wxString& operator=(const std::string& str)
{ return assign(str.c_str(), str.length()); }
#ifdef wxHAS_STD_STRING_VIEW
wxString& operator=(std::string_view view)
{ return assign(view.data(), view.length()); }
#endif // wxHAS_STD_STRING_VIEW
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
// string concatenation
// in place concatenation
/*

View file

@ -69,6 +69,11 @@ public:
virtual ~wxGLCanvasEGL();
// Wayland-specific callbacks
// --------------------------
void CreateWaylandSubsurface();
void DestroyWaylandSubsurface();
// implement wxGLCanvasBase methods
// --------------------------------

View file

@ -23,6 +23,10 @@ public:
/**
Retrieves the load address and the size of this module.
Note that under ELF systems (such as Linux) the region defined by the
parameters of this function can be discontinuous and contain multiple
segments belonging to the module with holes between them.
@param addr
The pointer to the location to return load address in, may be
@NULL.
@ -38,6 +42,8 @@ public:
/**
Returns the base name of this module, e.g.\ @c "kernel32.dll" or
@c "libc-2.3.2.so".
This name is empty for the main program itself.
*/
wxString GetName() const;
@ -217,13 +223,20 @@ public:
bool IsLoaded() const;
/**
This static method returns a wxArray containing the details of all
modules loaded into the address space of the current project. The array
elements are objects of the type: wxDynamicLibraryDetails. The array
will be empty if an error occurred.
This static method returns a vector-like object containing the details
of all modules loaded into the address space of the current project.
This method is currently implemented only under Win32 and Linux and is
useful mostly for diagnostics purposes.
The array elements are objects of the type wxDynamicLibraryDetails.
Under Unix systems they appear in the order in which they libraries
have been loaded, with the module corresponding to the main program
itself coming first.
The returned array will be empty if an error occurred or if the
function is not implemented for the current platform.
This method is currently implemented only under Win32 and Unix systems
providing `dl_iterate_phdr()` function (such as Linux) and is useful
mostly for diagnostics purposes.
*/
static wxDynamicLibraryDetailsArray ListLoaded();

View file

@ -164,7 +164,7 @@ public:
Returns @true if the hyperlink has already been clicked by the user at least
one time.
*/
virtual bool GetVisited() const = 0;
virtual bool GetVisited() const;
/**
Returns the colour used to print the label when the mouse is not over the
@ -195,7 +195,7 @@ public:
/**
Marks the hyperlink as visited (see wxHyperlinkCtrl::SetVisitedColour).
*/
virtual void SetVisited(bool visited = true) = 0;
virtual void SetVisited(bool visited = true);
/**
Sets the colour used to print the label when the mouse is not over the control

View file

@ -3773,6 +3773,9 @@ public:
applications (and probably avoid using it under the other
platforms without good reason as well).
@note This function does nothing when using wxGTK with Wayland because
Wayland intentionally doesn't provide the required functionality.
@param x
The new x position for the cursor.
@param y

View file

@ -937,6 +937,9 @@
/* Define if you have the dladdr function. */
#undef HAVE_DLADDR
/* Define if you have the dl_iterate_phdr function. */
#undef HAVE_DL_ITERATE_PHDR
/* Define if you have Posix fnctl() function. */
#undef HAVE_FCNTL

View file

@ -49,6 +49,7 @@
#endif // wxCrtSetDbgFlag
#endif // __WINDOWS__
#include "wx/private/init.h"
#include "wx/private/localeset.h"
#include <memory>
@ -121,38 +122,25 @@ static inline void Use(void *) { }
// initialization data
// ----------------------------------------------------------------------------
static struct InitData
namespace
{
InitData()
: nInitCount(0)
{
argc = argcOrig = 0;
// argv = argvOrig = nullptr; -- not even really needed
}
// number of times wxInitialize() was called minus the number of times
// wxUninitialize() was
//
// it is atomic to allow more than one thread to call wxInitialize() but
// only one of them to actually initialize the library
wxAtomicInt nInitCount;
wxAtomicInt gs_nInitCount{0};
int argc;
} // anonymous namespace
// if we receive the command line arguments as ASCII and have to convert
// them to Unicode ourselves (this is the case under Unix but not Windows,
// for example), we remember the converted argv here because we'll have to
// free it when doing cleanup to avoid memory leaks
wchar_t **argv;
/* static */
wxInitData& wxInitData::Get()
{
static wxInitData s_initData;
// we also need to keep two copies, one passed to other functions, and one
// unmodified original; somebody may modify the former, so we need to have
// the latter to be able to free everything correctly
int argcOrig;
wchar_t **argvOrig;
wxDECLARE_NO_COPY_CLASS(InitData);
} gs_initData;
return s_initData;
}
// ============================================================================
// implementation
@ -162,18 +150,23 @@ static struct InitData
// command line arguments ANSI -> Unicode conversion
// ----------------------------------------------------------------------------
static void ConvertArgsToUnicode(int argc, char **argv)
void wxInitData::Initialize(int argcIn, char **argvIn)
{
gs_initData.argvOrig = new wchar_t *[argc + 1];
gs_initData.argv = new wchar_t *[argc + 1];
wxASSERT_MSG( !argc && !argv, "initializing twice?" );
#ifndef __WINDOWS__
argvA = argvIn;
#endif
argv = new wchar_t *[argcIn + 1];
int wargc = 0;
for ( int i = 0; i < argc; i++ )
for ( int i = 0; i < argcIn; i++ )
{
#ifdef __DARWIN__
wxWCharBuffer buf(wxConvFileName->cMB2WX(argv[i]));
wxWCharBuffer buf(wxConvFileName->cMB2WX(argvIn[i]));
#else
wxWCharBuffer buf(wxConvLocal.cMB2WX(argv[i]));
wxWCharBuffer buf(wxConvLocal.cMB2WX(argvIn[i]));
#endif
if ( !buf )
{
@ -182,28 +175,58 @@ static void ConvertArgsToUnicode(int argc, char **argv)
}
else // converted ok
{
gs_initData.argvOrig[wargc] = gs_initData.argv[wargc] = wxStrdup(buf);
argv[wargc] = wxStrdup(buf);
wargc++;
}
}
gs_initData.argcOrig = gs_initData.argc = wargc;
gs_initData.argvOrig[wargc] =gs_initData.argv[wargc] = nullptr;
argc = wargc;
argv[wargc] = nullptr;
}
static void FreeConvertedArgs()
#ifdef __WINDOWS__
void wxInitData::MSWInitialize()
{
if ( gs_initData.argvOrig )
wxASSERT_MSG( !argc && !argvMSW, "initializing twice?" );
// Prefer to use the standard function for tokenizing the command line,
// instead of our own wxCmdLineParser::ConvertStringToArgs() which might
// not use exactly the same logic.
// This pointer will be freed in Free().
argvMSW = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
// And this one will be used by the rest of the code. It is separate from
// argvMSW because it could be allocated by Initialize() if a custom entry
// point is used.
argv = argvMSW;
}
#endif // __WINDOWS__
void wxInitData::Free()
{
#ifdef __WINDOWS__
if ( argvMSW )
{
for ( int i = 0; i < gs_initData.argcOrig; i++ )
::LocalFree(argvMSW);
// If argvMSW is non-null, argv must be the same value, so reset it too.
argv = argvMSW = nullptr;
argc = 0;
}
#endif // __WINDOWS__
if ( argc )
{
for ( int i = 0; i < argc; i++ )
{
free(gs_initData.argvOrig[i]);
// gs_initData.argv[i] normally points to the same data
free(argv[i]);
}
wxDELETEA(gs_initData.argvOrig);
wxDELETEA(gs_initData.argv);
gs_initData.argcOrig = gs_initData.argc = 0;
wxDELETEA(argv);
argc = 0;
}
}
@ -339,11 +362,12 @@ bool wxEntryStart(int& argc, wxChar **argv)
// we provide a wxEntryStart() wrapper taking "char *" pointer too
bool wxEntryStart(int& argc, char **argv)
{
ConvertArgsToUnicode(argc, argv);
auto& initData = wxInitData::Get();
initData.Initialize(argc, argv);
if ( !wxEntryStart(gs_initData.argc, gs_initData.argv) )
if ( !wxEntryStart(initData.argc, initData.argv) )
{
FreeConvertedArgs();
initData.Free();
return false;
}
@ -378,7 +402,7 @@ static void DoCommonPostCleanup()
// we can't do this in wxApp itself because it doesn't know if argv had
// been allocated
FreeConvertedArgs();
wxInitData::Get().Free();
// use Set(nullptr) and not Get() to avoid creating a message output object on
// demand when we just want to delete it
@ -401,12 +425,7 @@ static void DoCommonPostCleanup()
#endif // wxUSE_LOG
}
// for MSW the real wxEntryCleanup() is defined in msw/main.cpp
#ifndef __WINDOWS__
#define wxEntryCleanupReal wxEntryCleanup
#endif // !__WINDOWS__
void wxEntryCleanupReal()
void wxEntryCleanup()
{
DoCommonPreCleanup();
@ -478,9 +497,10 @@ int wxEntryReal(int& argc, wxChar **argv)
// as with wxEntryStart, we provide an ANSI wrapper
int wxEntry(int& argc, char **argv)
{
ConvertArgsToUnicode(argc, argv);
auto& initData = wxInitData::Get();
initData.Initialize(argc, argv);
return wxEntry(gs_initData.argc, gs_initData.argv);
return wxEntry(initData.argc, initData.argv);
}
// ----------------------------------------------------------------------------
@ -495,7 +515,7 @@ bool wxInitialize()
bool wxInitialize(int& argc, wxChar **argv)
{
if ( wxAtomicInc(gs_initData.nInitCount) != 1 )
if ( wxAtomicInc(gs_nInitCount) != 1 )
{
// already initialized
return true;
@ -506,7 +526,7 @@ bool wxInitialize(int& argc, wxChar **argv)
bool wxInitialize(int& argc, char **argv)
{
if ( wxAtomicInc(gs_initData.nInitCount) != 1 )
if ( wxAtomicInc(gs_nInitCount) != 1 )
{
// already initialized
return true;
@ -517,7 +537,7 @@ bool wxInitialize(int& argc, char **argv)
void wxUninitialize()
{
if ( wxAtomicDec(gs_initData.nInitCount) != 0 )
if ( wxAtomicDec(gs_nInitCount) != 0 )
return;
wxEntryCleanup();

View file

@ -1532,3 +1532,10 @@ WXLRESULT wxScrolledT_Helper::FilterMSWWindowProc(WXUINT nMsg, WXLRESULT rc)
// NB: skipping wxScrolled<T> in wxRTTI information because being a template,
// it doesn't and can't implement wxRTTI support
wxIMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel);
namespace wxPrivate
{
wxScrolledCanvasDummySubclass::wxScrolledCanvasDummySubclass() = default;
}

View file

@ -24,6 +24,8 @@
#include "wx/fontmap.h"
#include "wx/msgout.h"
#include "wx/private/init.h"
#include "wx/gtk/private.h"
#include "wx/gtk/private/log.h"
#include "wx/gtk/private/threads.h"
@ -472,19 +474,6 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
bool init_result;
int i;
// gtk_init() wants UTF-8, not wchar_t, so convert
char **argvGTK = new char *[argc_ + 1];
for ( i = 0; i < argc_; i++ )
{
argvGTK[i] = wxStrdupA(wxConvUTF8.cWX2MB(argv_[i]));
}
argvGTK[argc_] = nullptr;
int argcGTK = argc_;
// Prevent gtk_init_check() from changing the locale automatically for
// consistency with the other ports that don't do it. If necessary,
// wxApp::SetCLocale() may be explicitly called.
@ -501,36 +490,31 @@ bool wxApp::Initialize(int& argc_, wxChar **argv_)
#if defined(__WXGTK4__)
init_result = gtk_init_check() != 0;
#else
init_result = gtk_init_check( &argcGTK, &argvGTK ) != 0;
#endif
auto argvA = wxInitData::Get().argvA;
int argcGTK = argc_;
init_result = gtk_init_check( &argcGTK, &argvA ) != 0;
if ( argcGTK != argc_ )
{
// we have to drop the parameters which were consumed by GTK+
for ( i = 0; i < argcGTK; i++ )
for ( int i = 0; i < argcGTK; i++ )
{
while ( strcmp(wxConvUTF8.cWX2MB(argv_[i]), argvGTK[i]) != 0 )
while ( strcmp(wxConvUTF8.cWX2MB(argv_[i]), argvA[i]) != 0 )
{
free(argv_[i]);
memmove(argv_ + i, argv_ + i + 1, (argc_ - i)*sizeof(*argv_));
}
}
argc_ = argcGTK;
argv_[argc_] = nullptr;
this->argc = argc_;
this->argv.Init(argc_, argv_);
}
//else: gtk_init() didn't modify our parameters
// free our copy
for ( i = 0; i < argcGTK; i++ )
{
free(argvGTK[i]);
}
delete [] argvGTK;
// update internal arg[cv] as GTK+ may have removed processed options:
this->argc = argc_;
this->argv.Init(argc_, argv_);
#endif
if ( !init_result )
{

View file

@ -1054,7 +1054,7 @@ bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options)
gspell_entry_set_inline_spell_checking(spell, options.IsSpellCheckEnabled());
}
return GetProofCheckOptions().IsSpellCheckEnabled();
return GetProofCheckOptions().IsSpellCheckEnabled() == options.IsSpellCheckEnabled();
}
wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const
@ -1065,16 +1065,24 @@ wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const
{
GtkTextView *textview = GTK_TEXT_VIEW(m_text);
if ( textview && gspell_text_view_get_from_gtk_text_view(textview) )
opts.SpellCheck();
if ( textview )
{
GspellTextView *spell = gspell_text_view_get_from_gtk_text_view (textview);
if ( spell && gspell_text_view_get_inline_spell_checking(spell) )
opts.SpellCheck();
}
}
else
{
GtkEntry *entry = GTK_ENTRY(m_text);
if ( entry && gspell_entry_get_from_gtk_entry(entry) )
opts.SpellCheck();
if ( entry )
{
GspellEntry *spell = gspell_entry_get_from_gtk_entry(entry);
if ( spell && gspell_entry_get_inline_spell_checking(spell) )
opts.SpellCheck();
}
}
return opts;

View file

@ -63,32 +63,10 @@ bool wxGUIEventLoop::PreProcessMessage(WXMSG *msg)
wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hwnd);
wxWindow *wnd;
// this might happen if we're in a modeless dialog, or if a wx control has
// children which themselves were not created by wx (i.e. wxActiveX control children)
// this might happen a wx control has children which themselves were not
// created by wx (i.e. wxActiveX control children)
if ( !wndThis )
{
while ( hwnd && (::GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD ))
{
hwnd = ::GetParent(hwnd);
// If the control has a wx parent, break and give the parent a chance
// to process the window message
wndThis = wxGetWindowFromHWND((WXHWND)hwnd);
if (wndThis != nullptr)
break;
}
if ( !wndThis )
{
// this may happen if the event occurred in a standard modeless dialog (the
// only example of which I know of is the find/replace dialog) - then call
// IsDialogMessage() to make TAB navigation in it work
// NOTE: IsDialogMessage() just eats all the messages (i.e. returns true for
// them) if we call it for the control itself
return hwnd && ::IsDialogMessage(hwnd, msg) != 0;
}
}
return false;
if ( !AllowProcessing(wndThis) )
{

View file

@ -30,6 +30,10 @@
#include "wx/fdrepdlg.h"
// Use functions from src/msw/window.cpp
extern void wxRemoveHandleAssociation(wxWindowMSW *win);
extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
// ----------------------------------------------------------------------------
// functions prototypes
// ----------------------------------------------------------------------------
@ -334,6 +338,7 @@ wxFindReplaceDialog::~wxFindReplaceDialog()
m_isShown = false;
// and from destroying our window [again]
wxRemoveHandleAssociation(this);
m_hWnd = (WXHWND)nullptr;
}
@ -419,6 +424,7 @@ bool wxFindReplaceDialog::Show(bool show)
}
m_hWnd = (WXHWND)hwnd;
wxAssociateWinWithHandle(m_hWnd, this);
return true;
}
@ -440,6 +446,19 @@ wxString wxFindReplaceDialog::GetTitle() const
return m_title;
}
// ----------------------------------------------------------------------------
// wxFindReplaceDialog message handling
// ----------------------------------------------------------------------------
bool wxFindReplaceDialog::MSWProcessMessage(WXMSG* pMsg)
{
// The base class MSWProcessMessage() doesn't work for us because we don't
// have wxTAB_TRAVERSAL style, but then we don't need it anyhow: as this
// dialog only ever contains standard controls, just using the standard
// function is enough to make TAB navigation work in it.
return m_hWnd && ::IsDialogMessage(m_hWnd, pMsg);
}
// ----------------------------------------------------------------------------
// wxFindReplaceDialog position/size
// ----------------------------------------------------------------------------

View file

@ -28,6 +28,8 @@
#include "wx/dynlib.h"
#include "wx/private/init.h"
#include "wx/msw/private.h"
#include "wx/msw/seh.h"
@ -38,7 +40,6 @@
// defined in common/init.cpp
extern int wxEntryReal(int& argc, wxChar **argv);
extern void wxEntryCleanupReal();
// ============================================================================
// implementation: various entry points
@ -188,78 +189,6 @@ int wxEntry(int& argc, wxChar **argv)
// Windows-specific wxEntry
// ----------------------------------------------------------------------------
// Declare the functions used in wxCore to access the command line arguments
// data in wxBase.
WXDLLIMPEXP_BASE void wxMSWCommandLineInit();
WXDLLIMPEXP_BASE void wxMSWCommandLineCleanup();
WXDLLIMPEXP_BASE int& wxMSWCommandLineGetArgc();
WXDLLIMPEXP_BASE wchar_t** wxMSWCommandLineGetArgv();
#if wxUSE_BASE
namespace
{
struct wxMSWCommandLineArguments
{
wxMSWCommandLineArguments() { argc = 0; argv = nullptr; }
// Initialize this object from the current process command line.
//
// In Unicode build prefer to use the standard function for tokenizing the
// command line, but we can't use it with narrow strings, so use our own
// approximation instead then.
void Init()
{
argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
}
void Cleanup()
{
if ( argc )
{
::LocalFree(argv);
argc = 0;
}
}
~wxMSWCommandLineArguments()
{
Cleanup();
}
int argc;
wxChar **argv;
wxDECLARE_NO_COPY_CLASS(wxMSWCommandLineArguments);
};
static wxMSWCommandLineArguments wxArgs;
} // anonymous namespace
WXDLLIMPEXP_BASE void wxMSWCommandLineInit()
{
wxArgs.Init();
}
WXDLLIMPEXP_BASE void wxMSWCommandLineCleanup()
{
wxArgs.Cleanup();
}
WXDLLIMPEXP_BASE int& wxMSWCommandLineGetArgc()
{
return wxArgs.argc;
}
WXDLLIMPEXP_BASE wchar_t** wxMSWCommandLineGetArgv()
{
return wxArgs.argv;
}
#endif // wxUSE_BASE
#if wxUSE_GUI
// common part of wxMSW-specific wxEntryStart() and wxEntry() overloads
@ -274,7 +203,7 @@ wxMSWEntryCommon(HINSTANCE hInstance, int nCmdShow)
wxUnusedVar(nCmdShow);
#endif
wxMSWCommandLineInit();
wxInitData().Get().MSWInitialize();
return true;
}
@ -287,7 +216,8 @@ WXDLLEXPORT bool wxEntryStart(HINSTANCE hInstance,
if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
return false;
return wxEntryStart(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
auto& initData = wxInitData::Get();
return wxEntryStart(initData.argc, initData.argv);
}
WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
@ -298,7 +228,8 @@ WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
if ( !wxMSWEntryCommon(hInstance, nCmdShow) )
return -1;
return wxEntry(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
auto& initData = wxInitData::Get();
return wxEntry(initData.argc, initData.argv);
}
#endif // wxUSE_GUI
@ -311,16 +242,10 @@ WXDLLEXPORT int wxEntry(HINSTANCE hInstance,
int wxEntry()
{
wxMSWCommandLineInit();
wxInitData().Get().MSWInitialize();
return wxEntry(wxMSWCommandLineGetArgc(), wxMSWCommandLineGetArgv());
}
void wxEntryCleanup()
{
wxEntryCleanupReal();
wxMSWCommandLineCleanup();
auto& initData = wxInitData::Get();
return wxEntry(initData.argc, initData.argv);
}
HINSTANCE wxhInstance = 0;

View file

@ -878,7 +878,7 @@ bool wxTextCtrl::EnableProofCheck(const wxTextProofOptions& options)
::SendMessage(GetHwnd(), EM_SETLANGOPTIONS, 0, langOptions);
return GetProofCheckOptions().IsSpellCheckEnabled();
return GetProofCheckOptions().IsSpellCheckEnabled() == options.IsSpellCheckEnabled();
}
wxTextProofOptions wxTextCtrl::GetProofCheckOptions() const

View file

@ -291,7 +291,7 @@ void wxTraceMSWMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
#endif // wxDEBUG_LEVEL >= 2
void wxRemoveHandleAssociation(wxWindowMSW *win);
extern void wxRemoveHandleAssociation(wxWindowMSW *win);
extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
// get the text metrics for the current font
@ -7098,44 +7098,31 @@ wxWindow *wxGetActiveWindow()
extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
{
HWND hwnd = (HWND)hWnd;
if ( !hwnd )
return nullptr;
// For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
// by code in msw/radiobox.cpp), for all the others we just search up the
// window hierarchy
wxWindow *win = nullptr;
if ( hwnd )
{
win = wxFindWinFromHandle(hwnd);
if ( !win )
{
// spin control text buddy window should be mapped to spin ctrl
// itself so try it too
wxWindow *win = wxFindWinFromHandle(hwnd);
// spin control text buddy window should be mapped to spin ctrl
// itself so try it too
#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
if ( !win )
{
win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd);
}
#endif // wxUSE_SPINCTRL
}
}
while ( hwnd && !win )
if ( !win )
{
// this is a really ugly hack needed to avoid mistakenly returning the
// parent frame wxWindow for the find/replace modeless dialog HWND -
// this, in turn, is needed to call IsDialogMessage() from
// wxApp::ProcessMessage() as for this we must return nullptr from here
//
// FIXME: this is clearly not the best way to do it but I think we'll
// need to change HWND <-> wxWindow code more heavily than I can
// do it now to fix it
win = wxSpinCtrl::GetSpinForTextCtrl((WXHWND)hwnd);
}
#endif // wxUSE_SPINCTRL
while ( !win )
{
// Avoid going beyond the top level window (only they have owner in
// Win32) as we could find its owner wxFrame which would be unwanted.
if ( ::GetWindow(hwnd, GW_OWNER) )
{
// it's a dialog box, don't go upwards
break;
}
return nullptr;
hwnd = ::GetParent(hwnd);
if ( !hwnd )
return nullptr;
win = wxFindWinFromHandle(hwnd);
}

View file

@ -33,6 +33,10 @@
#include <dlfcn.h>
#endif
#ifdef HAVE_DL_ITERATE_PHDR
#include <link.h>
#endif
// if some flags are not supported, just ignore them
#ifndef RTLD_LAZY
#define RTLD_LAZY 0
@ -125,20 +129,38 @@ void wxDynamicLibrary::ReportError(const wxString& message,
// listing loaded modules
// ----------------------------------------------------------------------------
#ifdef HAVE_DL_ITERATE_PHDR
// wxDynamicLibraryDetails declares this class as its friend, so put the code
// initializing new details objects here
class wxDynamicLibraryDetailsCreator
{
public:
// create a new wxDynamicLibraryDetails from the given data
static wxDynamicLibraryDetails
New(void *start, void *end, const wxString& path)
static int Callback(dl_phdr_info* info, size_t /* size */, void* data)
{
const wxString path = wxString::FromUTF8(info->dlpi_name);
wxDynamicLibraryDetails details;
details.m_path = path;
details.m_name = path.AfterLast(wxT('/'));
details.m_address = start;
details.m_length = (char *)end - (char *)start;
// Find the first and last address belonging to this module.
decltype(info->dlpi_addr) start = 0, end = 0;
for ( decltype(info->dlpi_phnum) n = 0; n < info->dlpi_phnum; n++ )
{
const auto& segment = info->dlpi_phdr[n];
if ( !segment.p_vaddr || !segment.p_memsz )
continue;
if ( !start || segment.p_vaddr < start )
start = segment.p_vaddr;
if ( !end || segment.p_vaddr + segment.p_memsz > end )
end = segment.p_vaddr + segment.p_memsz;
}
details.m_address = wxUIntToPtr(info->dlpi_addr + start);
details.m_length = end - start;
// try to extract the library version from its name
const size_t posExt = path.rfind(wxT(".so"));
@ -161,78 +183,24 @@ public:
}
}
return details;
auto dlls = static_cast<wxDynamicLibraryDetailsArray*>(data);
dlls->push_back(std::move(details));
// Return 0 to keep iterating.
return 0;
}
};
#endif // HAVE_DL_ITERATE_PHDR
/* static */
wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
{
wxDynamicLibraryDetailsArray dlls;
#ifdef __LINUX__
// examine /proc/self/maps to find out what is loaded in our address space
wxFFile file(wxT("/proc/self/maps"));
if ( file.IsOpened() )
{
// details of the module currently being parsed
wxString pathCur;
void *startCur = nullptr,
*endCur = nullptr;
char path[1024];
char buf[1024];
while ( fgets(buf, WXSIZEOF(buf), file.fp()) )
{
// format is: "start-end perm offset maj:min inode path", see proc(5)
void *start,
*end;
switch ( sscanf(buf, "%p-%p %*4s %*p %*02x:%*02x %*d %1023s\n",
&start, &end, path) )
{
case 2:
// there may be no path column
path[0] = '\0';
break;
case 3:
// nothing to do, read everything we wanted
break;
default:
// chop '\n'
buf[strlen(buf) - 1] = '\0';
wxLogDebug(wxT("Failed to parse line \"%s\" in /proc/self/maps."),
buf);
continue;
}
wxASSERT_MSG( start >= endCur,
wxT("overlapping regions in /proc/self/maps?") );
wxString pathNew = wxString::FromAscii(path);
if ( pathCur.empty() )
{
// new module start
pathCur = pathNew;
startCur = start;
endCur = end;
}
else if ( pathCur == pathNew && endCur == end )
{
// continuation of the same module in the address space
endCur = end;
}
else // end of the current module
{
dlls.Add(wxDynamicLibraryDetailsCreator::New(startCur,
endCur,
pathCur));
pathCur.clear();
}
}
}
#endif // __LINUX__
#ifdef HAVE_DL_ITERATE_PHDR
dl_iterate_phdr(wxDynamicLibraryDetailsCreator::Callback, &dlls);
#endif // HAVE_DL_ITERATE_PHDR
return dlls;
}

View file

@ -389,6 +389,14 @@ EGLDisplay wxGLCanvasEGL::GetDisplay()
// Helper declared as friend in the header and so can access m_wlSubsurface.
void wxEGLUpdatePosition(wxGLCanvasEGL* win)
{
if ( !win->m_wlSubsurface )
{
// In some circumstances such as when reparenting a canvas between two hidden
// toplevel windows, GTK will call size-allocate before mapping the canvas
// Ignore the call, the position will be fixed when it is mapped
return;
}
int x, y;
gdk_window_get_origin(win->GTKGetDrawingWindow(), &x, &y);
wl_subsurface_set_position(win->m_wlSubsurface, x, y);
@ -439,6 +447,17 @@ static const struct wl_callback_listener wl_frame_listener = {
wl_frame_callback_handler
};
static gboolean gtk_glcanvas_map_callback(GtkWidget *, GdkEventAny *, wxGLCanvasEGL *win)
{
win->CreateWaylandSubsurface();
return FALSE;
}
static void gtk_glcanvas_unmap_callback(GtkWidget *, wxGLCanvasEGL *win)
{
win->DestroyWaylandSubsurface();
}
static void gtk_glcanvas_size_callback(GtkWidget *widget,
GtkAllocation *,
wxGLCanvasEGL *win)
@ -462,16 +481,16 @@ bool wxGLCanvasEGL::CreateSurface()
return false;
}
if ( m_surface != EGL_NO_SURFACE )
{
eglDestroySurface(m_surface, m_display);
m_surface = EGL_NO_SURFACE;
}
GdkWindow *window = GTKGetDrawingWindow();
#ifdef GDK_WINDOWING_X11
if (wxGTKImpl::IsX11(window))
{
if ( m_surface != EGL_NO_SURFACE )
{
eglDestroySurface(m_surface, m_display);
m_surface = EGL_NO_SURFACE;
}
m_xwindow = GDK_WINDOW_XID(window);
m_surface = eglCreatePlatformWindowSurface(m_display, *m_config,
&m_xwindow, nullptr);
@ -480,10 +499,16 @@ bool wxGLCanvasEGL::CreateSurface()
#ifdef GDK_WINDOWING_WAYLAND
if (wxGTKImpl::IsWayland(window))
{
if ( m_wlSurface )
{
// Already created (can happen when the canvas is un-realized then
// re-realized, for example, when the canvas is re-parented)
return true;
}
int w = gdk_window_get_width(window);
int h = gdk_window_get_height(window);
struct wl_display *display = gdk_wayland_display_get_wl_display(gdk_window_get_display(window));
struct wl_surface *surface = gdk_wayland_window_get_wl_surface(window);
struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &wl_registry_listener, this);
wl_display_roundtrip(display);
@ -494,21 +519,25 @@ bool wxGLCanvasEGL::CreateSurface()
}
m_wlSurface = wl_compositor_create_surface(m_wlCompositor);
m_wlRegion = wl_compositor_create_region(m_wlCompositor);
m_wlSubsurface = wl_subcompositor_get_subsurface(m_wlSubcompositor,
m_wlSurface,
surface);
wl_surface_set_input_region(m_wlSurface, m_wlRegion);
wl_subsurface_set_desync(m_wlSubsurface);
wxEGLUpdatePosition(this);
int scale = gdk_window_get_scale_factor(window);
wl_surface_set_buffer_scale(m_wlSurface, scale);
m_wlEGLWindow = wl_egl_window_create(m_wlSurface, w * scale,
h * scale);
m_surface = eglCreatePlatformWindowSurface(m_display, *m_config,
m_wlEGLWindow, nullptr);
m_wlFrameCallbackHandler = wl_surface_frame(surface);
wl_callback_add_listener(m_wlFrameCallbackHandler,
&wl_frame_listener, this);
// We need to use "map-event" instead of "map" to ensure that the
// widget's underlying Wayland surface has been created.
// Otherwise, gdk_wayland_window_get_wl_surface may return nullptr,
// for example when hiding then showing a window containing a canvas.
gtk_widget_add_events(m_widget, GDK_STRUCTURE_MASK);
g_signal_connect(m_widget, "map-event",
G_CALLBACK(gtk_glcanvas_map_callback), this);
// However, note the use of "unmap" instead of the later "unmap-event"
// Not unmapping the canvas as soon as possible causes problems when reparenting
g_signal_connect(m_widget, "unmap",
G_CALLBACK(gtk_glcanvas_unmap_callback), this);
g_signal_connect(m_widget, "size-allocate",
G_CALLBACK(gtk_glcanvas_size_callback), this);
@ -535,9 +564,39 @@ wxGLCanvasEGL::~wxGLCanvasEGL()
eglDestroySurface(m_display, m_surface);
#ifdef GDK_WINDOWING_WAYLAND
g_clear_pointer(&m_wlEGLWindow, wl_egl_window_destroy);
g_clear_pointer(&m_wlSubsurface, wl_subsurface_destroy);
g_clear_pointer(&m_wlSurface, wl_surface_destroy);
#endif
}
void wxGLCanvasEGL::CreateWaylandSubsurface()
{
#ifdef GDK_WINDOWING_WAYLAND
GdkWindow *window = GTKGetDrawingWindow();
struct wl_surface *surface = gdk_wayland_window_get_wl_surface(window);
m_wlSubsurface = wl_subcompositor_get_subsurface(m_wlSubcompositor,
m_wlSurface,
surface);
wl_subsurface_set_desync(m_wlSubsurface);
wxEGLUpdatePosition(this);
m_wlFrameCallbackHandler = wl_surface_frame(surface);
wl_callback_add_listener(m_wlFrameCallbackHandler,
&wl_frame_listener, this);
if ( m_surface == EGL_NO_SURFACE )
{
wxFAIL_MSG("Unable to create EGL surface");
return;
}
#endif
}
void wxGLCanvasEGL::DestroyWaylandSubsurface()
{
#ifdef GDK_WINDOWING_WAYLAND
g_clear_pointer(&m_wlSubsurface, wl_subsurface_destroy);
g_clear_pointer(&m_wlFrameCallbackHandler, wl_callback_destroy);
m_readyToDraw = false;
#endif
}

View file

@ -690,5 +690,14 @@ TEST_CASE("StdString::View", "[stdstring]")
std::string_view strViewInvalidUTF(strInvalidUTF);
CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) );
/* Ensure we don't clobber comparisons on base types */
std::string_view view = "abc";
const char *str = "abc";
CHECK( view == str );
std::wstring_view wview = L"abc";
const wchar_t *wstr = L"abc";
CHECK( wview == wstr );
}
#endif // wxHAS_STD_STRING_VIEW