diff --git a/build/cmake/setup.cmake b/build/cmake/setup.cmake index 6818972584..297a251f28 100644 --- a/build/cmake/setup.cmake +++ b/build/cmake/setup.cmake @@ -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) diff --git a/configure b/configure index 7f5e66c055..45662ab5d9 100755 --- a/configure +++ b/configure @@ -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 diff --git a/configure.ac b/configure.ac index 0a8fbe27df..ff4005d27a 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/docs/changes.txt b/docs/changes.txt index 174af147fa..624767ba25 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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. diff --git a/docs/doxygen/images/appear-about-simple-msw.png b/docs/doxygen/images/appear-about-simple-msw.png index 622d4122a6..b0bc412f74 100644 Binary files a/docs/doxygen/images/appear-about-simple-msw.png and b/docs/doxygen/images/appear-about-simple-msw.png differ diff --git a/docs/doxygen/images/appear-about-with-url-msw.png b/docs/doxygen/images/appear-about-with-url-msw.png index a70f4680bf..776757db2f 100644 Binary files a/docs/doxygen/images/appear-about-with-url-msw.png and b/docs/doxygen/images/appear-about-with-url-msw.png differ diff --git a/docs/doxygen/images/appear-animationctrl-msw.png b/docs/doxygen/images/appear-animationctrl-msw.png index 867234b006..ff24dd2bb8 100644 Binary files a/docs/doxygen/images/appear-animationctrl-msw.png and b/docs/doxygen/images/appear-animationctrl-msw.png differ diff --git a/docs/doxygen/images/appear-bitmapbutton-msw.png b/docs/doxygen/images/appear-bitmapbutton-msw.png index 0bbb75f4f0..790cd2a016 100644 Binary files a/docs/doxygen/images/appear-bitmapbutton-msw.png and b/docs/doxygen/images/appear-bitmapbutton-msw.png differ diff --git a/docs/doxygen/images/appear-bitmapcombobox-msw.png b/docs/doxygen/images/appear-bitmapcombobox-msw.png index 2323b94258..78c0f1c98d 100644 Binary files a/docs/doxygen/images/appear-bitmapcombobox-msw.png and b/docs/doxygen/images/appear-bitmapcombobox-msw.png differ diff --git a/docs/doxygen/images/appear-button-msw.png b/docs/doxygen/images/appear-button-msw.png index a05f23269e..2f41239183 100644 Binary files a/docs/doxygen/images/appear-button-msw.png and b/docs/doxygen/images/appear-button-msw.png differ diff --git a/docs/doxygen/images/appear-calendarctrl-msw.png b/docs/doxygen/images/appear-calendarctrl-msw.png index d24e183b4b..a785d84f96 100644 Binary files a/docs/doxygen/images/appear-calendarctrl-msw.png and b/docs/doxygen/images/appear-calendarctrl-msw.png differ diff --git a/docs/doxygen/images/appear-checkbox-msw.png b/docs/doxygen/images/appear-checkbox-msw.png index 4fb05bb62c..1019128b77 100644 Binary files a/docs/doxygen/images/appear-checkbox-msw.png and b/docs/doxygen/images/appear-checkbox-msw.png differ diff --git a/docs/doxygen/images/appear-checklistbox-msw.png b/docs/doxygen/images/appear-checklistbox-msw.png index e711b2f174..25798e6adf 100644 Binary files a/docs/doxygen/images/appear-checklistbox-msw.png and b/docs/doxygen/images/appear-checklistbox-msw.png differ diff --git a/docs/doxygen/images/appear-choice-msw.png b/docs/doxygen/images/appear-choice-msw.png index aa5a025e75..47c305453d 100644 Binary files a/docs/doxygen/images/appear-choice-msw.png and b/docs/doxygen/images/appear-choice-msw.png differ diff --git a/docs/doxygen/images/appear-choicebook-msw.png b/docs/doxygen/images/appear-choicebook-msw.png index 1a3ec5b02a..8977413ab7 100644 Binary files a/docs/doxygen/images/appear-choicebook-msw.png and b/docs/doxygen/images/appear-choicebook-msw.png differ diff --git a/docs/doxygen/images/appear-collapsiblepane-msw.png b/docs/doxygen/images/appear-collapsiblepane-msw.png index a29ec3b3f3..ac49cebb27 100644 Binary files a/docs/doxygen/images/appear-collapsiblepane-msw.png and b/docs/doxygen/images/appear-collapsiblepane-msw.png differ diff --git a/docs/doxygen/images/appear-colourpickerctrl-msw.png b/docs/doxygen/images/appear-colourpickerctrl-msw.png index 8ff9228ac8..fc8369dd1f 100644 Binary files a/docs/doxygen/images/appear-colourpickerctrl-msw.png and b/docs/doxygen/images/appear-colourpickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-combobox-msw.png b/docs/doxygen/images/appear-combobox-msw.png index e49c3b9f9c..26d06fdf5e 100644 Binary files a/docs/doxygen/images/appear-combobox-msw.png and b/docs/doxygen/images/appear-combobox-msw.png differ diff --git a/docs/doxygen/images/appear-comboctrl-msw.png b/docs/doxygen/images/appear-comboctrl-msw.png index 9b2faedb48..79ab405d76 100644 Binary files a/docs/doxygen/images/appear-comboctrl-msw.png and b/docs/doxygen/images/appear-comboctrl-msw.png differ diff --git a/docs/doxygen/images/appear-commandlinkbutton-msw.png b/docs/doxygen/images/appear-commandlinkbutton-msw.png index 228a70a75c..b5d874dd2b 100644 Binary files a/docs/doxygen/images/appear-commandlinkbutton-msw.png and b/docs/doxygen/images/appear-commandlinkbutton-msw.png differ diff --git a/docs/doxygen/images/appear-dataviewctrl-msw.png b/docs/doxygen/images/appear-dataviewctrl-msw.png index 17c58d4a0c..0bbcb4be76 100644 Binary files a/docs/doxygen/images/appear-dataviewctrl-msw.png and b/docs/doxygen/images/appear-dataviewctrl-msw.png differ diff --git a/docs/doxygen/images/appear-dataviewtreectrl-msw.png b/docs/doxygen/images/appear-dataviewtreectrl-msw.png index c18e144cf3..01d4889330 100644 Binary files a/docs/doxygen/images/appear-dataviewtreectrl-msw.png and b/docs/doxygen/images/appear-dataviewtreectrl-msw.png differ diff --git a/docs/doxygen/images/appear-datepickerctrl-msw.png b/docs/doxygen/images/appear-datepickerctrl-msw.png index 7b2e7b72dd..81516df335 100644 Binary files a/docs/doxygen/images/appear-datepickerctrl-msw.png and b/docs/doxygen/images/appear-datepickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-dirpickerctrl-msw.png b/docs/doxygen/images/appear-dirpickerctrl-msw.png index 9b5e6704b2..64c7fbe415 100644 Binary files a/docs/doxygen/images/appear-dirpickerctrl-msw.png and b/docs/doxygen/images/appear-dirpickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-filectrl-msw.png b/docs/doxygen/images/appear-filectrl-msw.png index 910e972129..0d5694df21 100644 Binary files a/docs/doxygen/images/appear-filectrl-msw.png and b/docs/doxygen/images/appear-filectrl-msw.png differ diff --git a/docs/doxygen/images/appear-filepickerctrl-msw.png b/docs/doxygen/images/appear-filepickerctrl-msw.png index 0ecb94b146..6275f03eea 100644 Binary files a/docs/doxygen/images/appear-filepickerctrl-msw.png and b/docs/doxygen/images/appear-filepickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-fontpickerctrl-msw.png b/docs/doxygen/images/appear-fontpickerctrl-msw.png index ee4841ef39..d8efc3702e 100644 Binary files a/docs/doxygen/images/appear-fontpickerctrl-msw.png and b/docs/doxygen/images/appear-fontpickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-gauge-msw.png b/docs/doxygen/images/appear-gauge-msw.png index 1b86ced613..40e48ff4da 100644 Binary files a/docs/doxygen/images/appear-gauge-msw.png and b/docs/doxygen/images/appear-gauge-msw.png differ diff --git a/docs/doxygen/images/appear-genericdirctrl-msw.png b/docs/doxygen/images/appear-genericdirctrl-msw.png index e4edcb08ae..508ec617e9 100644 Binary files a/docs/doxygen/images/appear-genericdirctrl-msw.png and b/docs/doxygen/images/appear-genericdirctrl-msw.png differ diff --git a/docs/doxygen/images/appear-hyperlinkctrl-msw.png b/docs/doxygen/images/appear-hyperlinkctrl-msw.png index f5fed69f33..1a584203b9 100644 Binary files a/docs/doxygen/images/appear-hyperlinkctrl-msw.png and b/docs/doxygen/images/appear-hyperlinkctrl-msw.png differ diff --git a/docs/doxygen/images/appear-listbook-msw.png b/docs/doxygen/images/appear-listbook-msw.png index 4c63b51901..5132b3dd35 100644 Binary files a/docs/doxygen/images/appear-listbook-msw.png and b/docs/doxygen/images/appear-listbook-msw.png differ diff --git a/docs/doxygen/images/appear-listbox-msw.png b/docs/doxygen/images/appear-listbox-msw.png index a90d745e01..979c25b567 100644 Binary files a/docs/doxygen/images/appear-listbox-msw.png and b/docs/doxygen/images/appear-listbox-msw.png differ diff --git a/docs/doxygen/images/appear-listctrl-msw.png b/docs/doxygen/images/appear-listctrl-msw.png index fa828d512a..30386f398b 100644 Binary files a/docs/doxygen/images/appear-listctrl-msw.png and b/docs/doxygen/images/appear-listctrl-msw.png differ diff --git a/docs/doxygen/images/appear-notebook-msw.png b/docs/doxygen/images/appear-notebook-msw.png index abd65402b2..0ceba9799e 100644 Binary files a/docs/doxygen/images/appear-notebook-msw.png and b/docs/doxygen/images/appear-notebook-msw.png differ diff --git a/docs/doxygen/images/appear-ownerdrawncombobox-msw.png b/docs/doxygen/images/appear-ownerdrawncombobox-msw.png index 470f8ebef8..5ee966a224 100644 Binary files a/docs/doxygen/images/appear-ownerdrawncombobox-msw.png and b/docs/doxygen/images/appear-ownerdrawncombobox-msw.png differ diff --git a/docs/doxygen/images/appear-propertygrid-msw.png b/docs/doxygen/images/appear-propertygrid-msw.png index b5f2b1a5cf..4d22849925 100644 Binary files a/docs/doxygen/images/appear-propertygrid-msw.png and b/docs/doxygen/images/appear-propertygrid-msw.png differ diff --git a/docs/doxygen/images/appear-radiobox-msw.png b/docs/doxygen/images/appear-radiobox-msw.png index 6576b031a7..806bf6c456 100644 Binary files a/docs/doxygen/images/appear-radiobox-msw.png and b/docs/doxygen/images/appear-radiobox-msw.png differ diff --git a/docs/doxygen/images/appear-radiobutton-msw.png b/docs/doxygen/images/appear-radiobutton-msw.png index 1bf7b62c2a..859f2a2f6a 100644 Binary files a/docs/doxygen/images/appear-radiobutton-msw.png and b/docs/doxygen/images/appear-radiobutton-msw.png differ diff --git a/docs/doxygen/images/appear-richtextctrl-msw.png b/docs/doxygen/images/appear-richtextctrl-msw.png index 7a16f87506..febef55c6f 100644 Binary files a/docs/doxygen/images/appear-richtextctrl-msw.png and b/docs/doxygen/images/appear-richtextctrl-msw.png differ diff --git a/docs/doxygen/images/appear-richtooltip-msw.png b/docs/doxygen/images/appear-richtooltip-msw.png index afc7152a06..aad00800fd 100644 Binary files a/docs/doxygen/images/appear-richtooltip-msw.png and b/docs/doxygen/images/appear-richtooltip-msw.png differ diff --git a/docs/doxygen/images/appear-scrollbar-msw.png b/docs/doxygen/images/appear-scrollbar-msw.png index 5d37b51f82..1bb8ba869f 100644 Binary files a/docs/doxygen/images/appear-scrollbar-msw.png and b/docs/doxygen/images/appear-scrollbar-msw.png differ diff --git a/docs/doxygen/images/appear-searchctrl-msw.png b/docs/doxygen/images/appear-searchctrl-msw.png index e18743819e..7476cdeac5 100644 Binary files a/docs/doxygen/images/appear-searchctrl-msw.png and b/docs/doxygen/images/appear-searchctrl-msw.png differ diff --git a/docs/doxygen/images/appear-slider-msw.png b/docs/doxygen/images/appear-slider-msw.png index f99ca1430e..de45454c2c 100644 Binary files a/docs/doxygen/images/appear-slider-msw.png and b/docs/doxygen/images/appear-slider-msw.png differ diff --git a/docs/doxygen/images/appear-spinbutton-msw.png b/docs/doxygen/images/appear-spinbutton-msw.png index 88efe02f53..e5f14a22bc 100644 Binary files a/docs/doxygen/images/appear-spinbutton-msw.png and b/docs/doxygen/images/appear-spinbutton-msw.png differ diff --git a/docs/doxygen/images/appear-spinctrl-msw.png b/docs/doxygen/images/appear-spinctrl-msw.png index 4b7b9687ff..122fcd4109 100644 Binary files a/docs/doxygen/images/appear-spinctrl-msw.png and b/docs/doxygen/images/appear-spinctrl-msw.png differ diff --git a/docs/doxygen/images/appear-spinctrldouble-msw.png b/docs/doxygen/images/appear-spinctrldouble-msw.png index 21761111bf..4abd5925bc 100644 Binary files a/docs/doxygen/images/appear-spinctrldouble-msw.png and b/docs/doxygen/images/appear-spinctrldouble-msw.png differ diff --git a/docs/doxygen/images/appear-staticbitmap-msw.png b/docs/doxygen/images/appear-staticbitmap-msw.png index 0924a34b7f..f62aaa7cf1 100644 Binary files a/docs/doxygen/images/appear-staticbitmap-msw.png and b/docs/doxygen/images/appear-staticbitmap-msw.png differ diff --git a/docs/doxygen/images/appear-staticbox-msw.png b/docs/doxygen/images/appear-staticbox-msw.png index 6e105de3a8..aa2d822665 100644 Binary files a/docs/doxygen/images/appear-staticbox-msw.png and b/docs/doxygen/images/appear-staticbox-msw.png differ diff --git a/docs/doxygen/images/appear-statictext-msw.png b/docs/doxygen/images/appear-statictext-msw.png index 877761f424..4ca94e4ea0 100644 Binary files a/docs/doxygen/images/appear-statictext-msw.png and b/docs/doxygen/images/appear-statictext-msw.png differ diff --git a/docs/doxygen/images/appear-textctrl-msw.png b/docs/doxygen/images/appear-textctrl-msw.png index 0f127e71f5..987b41f749 100644 Binary files a/docs/doxygen/images/appear-textctrl-msw.png and b/docs/doxygen/images/appear-textctrl-msw.png differ diff --git a/docs/doxygen/images/appear-timepickerctrl-msw.png b/docs/doxygen/images/appear-timepickerctrl-msw.png index 8cc4fdd76f..aeab94cff5 100644 Binary files a/docs/doxygen/images/appear-timepickerctrl-msw.png and b/docs/doxygen/images/appear-timepickerctrl-msw.png differ diff --git a/docs/doxygen/images/appear-togglebutton-msw.png b/docs/doxygen/images/appear-togglebutton-msw.png index 0cfe4fd26a..992347cabb 100644 Binary files a/docs/doxygen/images/appear-togglebutton-msw.png and b/docs/doxygen/images/appear-togglebutton-msw.png differ diff --git a/docs/doxygen/images/appear-treectrl-msw.png b/docs/doxygen/images/appear-treectrl-msw.png index 8be3310b33..d390c93f12 100644 Binary files a/docs/doxygen/images/appear-treectrl-msw.png and b/docs/doxygen/images/appear-treectrl-msw.png differ diff --git a/docs/doxygen/images/generic/rearrangectrl.png b/docs/doxygen/images/generic/rearrangectrl.png index 452c4bfa3a..d63fe009ba 100644 Binary files a/docs/doxygen/images/generic/rearrangectrl.png and b/docs/doxygen/images/generic/rearrangectrl.png differ diff --git a/docs/doxygen/images/generic/rearrangelist.png b/docs/doxygen/images/generic/rearrangelist.png index 4c975a7e8c..196e1a069e 100644 Binary files a/docs/doxygen/images/generic/rearrangelist.png and b/docs/doxygen/images/generic/rearrangelist.png differ diff --git a/docs/doxygen/images/generic/simplehtmllistbox.png b/docs/doxygen/images/generic/simplehtmllistbox.png index ac1a5eddcc..2df44c6d6a 100644 Binary files a/docs/doxygen/images/generic/simplehtmllistbox.png and b/docs/doxygen/images/generic/simplehtmllistbox.png differ diff --git a/docs/doxygen/images/overview_splitter_3d.png b/docs/doxygen/images/overview_splitter_3d.png index 11e43f6e2f..ce988ee020 100644 Binary files a/docs/doxygen/images/overview_splitter_3d.png and b/docs/doxygen/images/overview_splitter_3d.png differ diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 8fde4b0aa0..9cf435a3f2 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -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 diff --git a/include/wx/msw/fdrepdlg.h b/include/wx/msw/fdrepdlg.h index 5884351cd4..9ccf2a6e12 100644 --- a/include/wx/msw/fdrepdlg.h +++ b/include/wx/msw/fdrepdlg.h @@ -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; diff --git a/include/wx/private/init.h b/include/wx/private/init.h new file mode 100644 index 0000000000..f2368ee32e --- /dev/null +++ b/include/wx/private/init.h @@ -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 +// 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_ diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index 417a901597..92dda56457 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -500,4 +500,17 @@ public: typedef wxScrolled 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_ diff --git a/include/wx/string.h b/include/wx/string.h index be59395409..a324feef06 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -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 /* diff --git a/include/wx/unix/glegl.h b/include/wx/unix/glegl.h index 59e830e4da..f6d455b397 100644 --- a/include/wx/unix/glegl.h +++ b/include/wx/unix/glegl.h @@ -69,6 +69,11 @@ public: virtual ~wxGLCanvasEGL(); + // Wayland-specific callbacks + // -------------------------- + + void CreateWaylandSubsurface(); + void DestroyWaylandSubsurface(); // implement wxGLCanvasBase methods // -------------------------------- diff --git a/interface/wx/dynlib.h b/interface/wx/dynlib.h index 43fdf48225..9fc0b12122 100644 --- a/interface/wx/dynlib.h +++ b/interface/wx/dynlib.h @@ -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(); diff --git a/interface/wx/hyperlink.h b/interface/wx/hyperlink.h index 4e51d41d41..9cbf707ee8 100644 --- a/interface/wx/hyperlink.h +++ b/interface/wx/hyperlink.h @@ -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 diff --git a/interface/wx/window.h b/interface/wx/window.h index b1491a5abb..392f1aa3a6 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -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 diff --git a/setup.h.in b/setup.h.in index d1143e178a..077a12ad16 100644 --- a/setup.h.in +++ b/setup.h.in @@ -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 diff --git a/src/common/init.cpp b/src/common/init.cpp index e3b315d28b..cdd8dd1239 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -49,6 +49,7 @@ #endif // wxCrtSetDbgFlag #endif // __WINDOWS__ +#include "wx/private/init.h" #include "wx/private/localeset.h" #include @@ -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(); diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index f1e700193d..4f347509be 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -1532,3 +1532,10 @@ WXLRESULT wxScrolledT_Helper::FilterMSWWindowProc(WXUINT nMsg, WXLRESULT rc) // NB: skipping wxScrolled 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; + +} diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index c350e6ca17..f72d777867 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -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 ) { diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 7c26308a14..41e5279bd3 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -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; diff --git a/src/msw/evtloop.cpp b/src/msw/evtloop.cpp index 34018e8bee..c5d2f1ca71 100644 --- a/src/msw/evtloop.cpp +++ b/src/msw/evtloop.cpp @@ -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) ) { diff --git a/src/msw/fdrepdlg.cpp b/src/msw/fdrepdlg.cpp index 52b9505063..c50ff773c9 100644 --- a/src/msw/fdrepdlg.cpp +++ b/src/msw/fdrepdlg.cpp @@ -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 // ---------------------------------------------------------------------------- diff --git a/src/msw/main.cpp b/src/msw/main.cpp index 01dc56b298..f582f73cc9 100644 --- a/src/msw/main.cpp +++ b/src/msw/main.cpp @@ -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; diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 6f15bb6284..c46f40cf91 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -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 diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 444634f9b6..dbfadaa73c 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -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); } diff --git a/src/unix/dlunix.cpp b/src/unix/dlunix.cpp index 876738437e..144120504c 100644 --- a/src/unix/dlunix.cpp +++ b/src/unix/dlunix.cpp @@ -33,6 +33,10 @@ #include #endif +#ifdef HAVE_DL_ITERATE_PHDR + #include +#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(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; } diff --git a/src/unix/glegl.cpp b/src/unix/glegl.cpp index 4236ff06a8..7b177cd5c8 100644 --- a/src/unix/glegl.cpp +++ b/src/unix/glegl.cpp @@ -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 } diff --git a/tests/strings/stdstrings.cpp b/tests/strings/stdstrings.cpp index f3ff37f2ee..c695dd21fc 100644 --- a/tests/strings/stdstrings.cpp +++ b/tests/strings/stdstrings.cpp @@ -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