From 2451f8085be6ced9ac8e5b2595e0b43bf50599d9 Mon Sep 17 00:00:00 2001 From: Pavel Tyunin Date: Thu, 25 Feb 2021 21:23:33 +0200 Subject: [PATCH 01/23] Fix search in wxSortedArrayString with custom compare function --- include/wx/arrstr.h | 3 ++ src/common/arrstr.cpp | 70 ++++++++++++++++------------------------- tests/arrays/arrays.cpp | 5 +++ 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index e21dc78761..bed1098d74 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -398,6 +398,9 @@ private: // (if the old buffer is big enough, just return NULL). wxString *Grow(size_t nIncrement); + // Binary search in the sorted array + size_t BinarySearch(const wxString& str, bool equal = false) const; + size_t m_nSize, // current size of the array m_nCount; // current number of elements diff --git a/src/common/arrstr.cpp b/src/common/arrstr.cpp index dc569a80bf..3aac42f67d 100644 --- a/src/common/arrstr.cpp +++ b/src/common/arrstr.cpp @@ -377,6 +377,29 @@ void wxArrayString::Shrink() } } +// Binary search in the sorted array +size_t wxArrayString::BinarySearch(const wxString& str, bool equal) const +{ + size_t + lo = 0, + hi = m_nCount; + while (lo < hi) { + size_t i; + i = (lo + hi) / 2; + + int res; + res = m_compareFunction ? m_compareFunction(str, m_pItems[i]) : str.Cmp(m_pItems[i]); + if (res < 0) + hi = i; + else if (res > 0) + lo = i + 1; + else + return i; + } + wxASSERT_MSG(lo == hi, wxT("binary search broken")); + return equal ? wxNOT_FOUND : lo; +} + // searches the array for an item (forward or backwards) int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const { @@ -384,25 +407,7 @@ int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const // use binary search in the sorted array wxASSERT_MSG( bCase && !bFromEnd, wxT("search parameters ignored for auto sorted array") ); - - size_t - lo = 0, - hi = m_nCount; - while ( lo < hi ) { - size_t i; - i = (lo + hi)/2; - - int res; - res = str.compare(m_pItems[i]); - if ( res < 0 ) - hi = i; - else if ( res > 0 ) - lo = i + 1; - else - return i; - } - - return wxNOT_FOUND; + return BinarySearch(str, true); } else { // use linear search in unsorted array @@ -432,30 +437,9 @@ size_t wxArrayString::Add(const wxString& str, size_t nInsert) { if ( m_autoSort ) { // insert the string at the correct position to keep the array sorted - size_t - lo = 0, - hi = m_nCount; - while ( lo < hi ) { - size_t i; - i = (lo + hi)/2; - - int res; - res = m_compareFunction ? m_compareFunction(str, m_pItems[i]) : str.Cmp(m_pItems[i]); - if ( res < 0 ) - hi = i; - else if ( res > 0 ) - lo = i + 1; - else { - lo = hi = i; - break; - } - } - - wxASSERT_MSG( lo == hi, wxT("binary search broken") ); - - Insert(str, lo, nInsert); - - return (size_t)lo; + size_t nIndex = BinarySearch(str); + Insert(str, nIndex, nInsert); + return nIndex; } else { // Now that we must postpone freeing the old memory until we don't need it diff --git a/tests/arrays/arrays.cpp b/tests/arrays/arrays.cpp index 3f61c4ff41..6c815eb52f 100644 --- a/tests/arrays/arrays.cpp +++ b/tests/arrays/arrays.cpp @@ -399,6 +399,11 @@ void ArraysTestCase::SortedArray() ad.Add("Aa"); CPPUNIT_ASSERT_EQUAL( "a", ad[0] ); CPPUNIT_ASSERT_EQUAL( "Aa", ad[1] ); + CPPUNIT_ASSERT_EQUAL( 0, ad.Index("a") ); + CPPUNIT_ASSERT_EQUAL( 1, ad.Index("Aa") ); + CPPUNIT_ASSERT_EQUAL( 2, ad.Index("AB") ); + CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("A") ); + CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("z") ); } void ArraysTestCase::wxStringArraySplitTest() From 00fec01308d6cdfbb0edb945cb7c45d0cce1afc9 Mon Sep 17 00:00:00 2001 From: Pavel Tyunin Date: Fri, 26 Feb 2021 11:52:44 +0200 Subject: [PATCH 02/23] Fex search in wxSortedArrayString with custom compare function in STL build --- include/wx/dynarray.h | 3 +++ src/common/arrstr.cpp | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index 67dc5e6f5e..03cb8c6c1f 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -255,6 +255,9 @@ public: Add(item); } +protected: + SCMPFUNC GetCompareFunction() const wxNOEXCEPT { return m_fnCompare; } + private: SCMPFUNC m_fnCompare; }; diff --git a/src/common/arrstr.cpp b/src/common/arrstr.cpp index 3aac42f67d..3611bc4276 100644 --- a/src/common/arrstr.cpp +++ b/src/common/arrstr.cpp @@ -198,15 +198,16 @@ int wxSortedArrayString::Index(const wxString& str, wxASSERT_MSG( bCase && !bFromEnd, "search parameters ignored for sorted array" ); + SCMPFUNC function = GetCompareFunction(); wxSortedArrayString::const_iterator it = std::lower_bound(begin(), end(), str, #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(14) - [](const wxString& s1, const wxString& s2) + [function](const wxString& s1, const wxString& s2) { - return s1 < s2; + return function(s1, s2) < 0; } #else // C++98 version - wxStringCompare(wxStringCmp()) + wxStringCompare(function) #endif // C++11/C++98 ); From 6819b5512bf1fb1652cab3d83f0ba509f6ad1b44 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 26 Feb 2021 16:25:28 +0100 Subject: [PATCH 03/23] Make BinarySearch() interface slightly more readable Replace "equal" parameter with the (opposite) "lowerBound" one with a more descriptive name, add a comment describing it and also remove the default value to force explaining how it is used in the caller. No real changes. --- include/wx/arrstr.h | 6 ++++-- src/common/arrstr.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index bed1098d74..951dd16d1b 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -398,8 +398,10 @@ private: // (if the old buffer is big enough, just return NULL). wxString *Grow(size_t nIncrement); - // Binary search in the sorted array - size_t BinarySearch(const wxString& str, bool equal = false) const; + // Binary search in the sorted array: return the index of the string if it's + // present, otherwise, if lowerBound is true, return the position at which + // the string should be inserted and if it's false return wxNOT_FOUND. + size_t BinarySearch(const wxString& str, bool lowerBound) const; size_t m_nSize, // current size of the array m_nCount; // current number of elements diff --git a/src/common/arrstr.cpp b/src/common/arrstr.cpp index 3611bc4276..65317bb1e8 100644 --- a/src/common/arrstr.cpp +++ b/src/common/arrstr.cpp @@ -379,7 +379,7 @@ void wxArrayString::Shrink() } // Binary search in the sorted array -size_t wxArrayString::BinarySearch(const wxString& str, bool equal) const +size_t wxArrayString::BinarySearch(const wxString& str, bool lowerBound) const { size_t lo = 0, @@ -398,7 +398,7 @@ size_t wxArrayString::BinarySearch(const wxString& str, bool equal) const return i; } wxASSERT_MSG(lo == hi, wxT("binary search broken")); - return equal ? wxNOT_FOUND : lo; + return lowerBound ? lo : wxNOT_FOUND; } // searches the array for an item (forward or backwards) @@ -408,7 +408,7 @@ int wxArrayString::Index(const wxString& str, bool bCase, bool bFromEnd) const // use binary search in the sorted array wxASSERT_MSG( bCase && !bFromEnd, wxT("search parameters ignored for auto sorted array") ); - return BinarySearch(str, true); + return BinarySearch(str, false /* not lower bound */); } else { // use linear search in unsorted array @@ -438,7 +438,7 @@ size_t wxArrayString::Add(const wxString& str, size_t nInsert) { if ( m_autoSort ) { // insert the string at the correct position to keep the array sorted - size_t nIndex = BinarySearch(str); + size_t nIndex = BinarySearch(str, true /* return lower bound */); Insert(str, nIndex, nInsert); return nIndex; } From eb3fdfe82fcbc63369667db1b946d983f6834c1b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 26 Feb 2021 16:32:45 +0100 Subject: [PATCH 04/23] Get rid of ArraysTestCase class in the dyn arrays unit tests Just remove more CppUnit boilerplate, no real changes. --- tests/arrays/arrays.cpp | 78 ++++++++--------------------------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/tests/arrays/arrays.cpp b/tests/arrays/arrays.cpp index 6c815eb52f..49575dd301 100644 --- a/tests/arrays/arrays.cpp +++ b/tests/arrays/arrays.cpp @@ -156,60 +156,10 @@ struct Item WX_DEFINE_ARRAY_PTR(Item *, ItemPtrArray); // ---------------------------------------------------------------------------- -// test class +// the tests // ---------------------------------------------------------------------------- -class ArraysTestCase : public CppUnit::TestCase -{ -public: - ArraysTestCase() { } - -private: - CPPUNIT_TEST_SUITE( ArraysTestCase ); - CPPUNIT_TEST( wxStringArrayTest ); - CPPUNIT_TEST( SortedArray ); - CPPUNIT_TEST( wxStringArraySplitTest ); - CPPUNIT_TEST( wxStringArrayJoinTest ); - CPPUNIT_TEST( wxStringArraySplitJoinTest ); - - CPPUNIT_TEST( wxObjArrayTest ); - CPPUNIT_TEST( wxObjArrayPtrTest ); - CPPUNIT_TEST( wxArrayUShortTest ); - CPPUNIT_TEST( wxArrayIntTest ); - CPPUNIT_TEST( wxArrayCharTest ); - CPPUNIT_TEST( TestSTL ); - CPPUNIT_TEST( Alloc ); - CPPUNIT_TEST( Clear ); - CPPUNIT_TEST( Swap ); - CPPUNIT_TEST( IndexFromEnd ); - CPPUNIT_TEST_SUITE_END(); - - void wxStringArrayTest(); - void SortedArray(); - void wxStringArraySplitTest(); - void wxStringArrayJoinTest(); - void wxStringArraySplitJoinTest(); - void wxObjArrayTest(); - void wxObjArrayPtrTest(); - void wxArrayUShortTest(); - void wxArrayIntTest(); - void wxArrayCharTest(); - void TestSTL(); - void Alloc(); - void Clear(); - void Swap(); - void IndexFromEnd(); - - wxDECLARE_NO_COPY_CLASS(ArraysTestCase); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( ArraysTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ArraysTestCase, "ArraysTestCase" ); - -void ArraysTestCase::wxStringArrayTest() +TEST_CASE("wxArrayString", "[dynarray]") { wxArrayString a1; a1.Add(wxT("thermit")); @@ -375,7 +325,7 @@ void ArraysTestCase::wxStringArrayTest() wxCLANG_WARNING_RESTORE(self-assign-overloaded) } -void ArraysTestCase::SortedArray() +TEST_CASE("wxSortedArrayString", "[dynarray]") { wxSortedArrayString a; a.Add("d"); @@ -406,7 +356,7 @@ void ArraysTestCase::SortedArray() CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("z") ); } -void ArraysTestCase::wxStringArraySplitTest() +TEST_CASE("Arrays::Split", "[dynarray]") { // test wxSplit: @@ -461,7 +411,7 @@ void ArraysTestCase::wxStringArraySplitTest() } } -void ArraysTestCase::wxStringArrayJoinTest() +TEST_CASE("Arrays::Join", "[dynarray]") { // test wxJoin: @@ -506,7 +456,7 @@ void ArraysTestCase::wxStringArrayJoinTest() } } -void ArraysTestCase::wxStringArraySplitJoinTest() +TEST_CASE("Arrays::SplitJoin", "[dynarray]") { wxChar separators[] = { wxT('a'), wxT(','), wxT('_'), wxT(' '), wxT('\\'), wxT('&'), wxT('{'), wxT('A'), wxT('<'), wxT('>'), @@ -560,7 +510,7 @@ void ArraysTestCase::wxStringArraySplitJoinTest() CPPUNIT_ASSERT_EQUAL( 2, wxSplit(wxT(";"), wxT(';')).size() ); } -void ArraysTestCase::wxObjArrayTest() +TEST_CASE("wxObjArray", "[dynarray]") { { ArrayBars bars; @@ -588,7 +538,7 @@ void ArraysTestCase::wxObjArrayTest() CPPUNIT_ASSERT_EQUAL( 0, Bar::GetNumber() ); } -void ArraysTestCase::wxObjArrayPtrTest() +TEST_CASE("wxObjArrayPtr", "[dynarray]") { // Just check that instantiating this class compiles. ArrayBarPtrs barptrs; @@ -597,7 +547,7 @@ void ArraysTestCase::wxObjArrayPtrTest() #define TestArrayOf(name) \ \ -void ArraysTestCase::wxArray ## name ## Test() \ +TEST_CASE("wxDynArray::" #name, "[dynarray]") \ { \ wxArray##name a; \ a.Add(1); \ @@ -642,7 +592,7 @@ TestArrayOf(Char) TestArrayOf(Int) -void ArraysTestCase::Alloc() +TEST_CASE("wxDynArray::Alloc", "[dynarray]") { wxArrayInt a; a.Add(17); @@ -656,7 +606,7 @@ void ArraysTestCase::Alloc() CPPUNIT_ASSERT_EQUAL( 9, a[1] ); } -void ArraysTestCase::Clear() +TEST_CASE("wxDynArray::Clear", "[dynarray]") { ItemPtrArray items; @@ -702,7 +652,7 @@ void DoTestSwap(T v1, T v2, T v3) } // anonymous namespace -void ArraysTestCase::Swap() +TEST_CASE("wxDynArray::Swap", "[dynarray]") { DoTestSwap("Foo", "Bar", "Baz"); @@ -710,7 +660,7 @@ void ArraysTestCase::Swap() DoTestSwap(6, 28, 496); } -void ArraysTestCase::TestSTL() +TEST_CASE("wxDynArray::TestSTL", "[dynarray]") { wxArrayInt list1; wxArrayInt::iterator it, en; @@ -768,7 +718,7 @@ void ArraysTestCase::TestSTL() WX_CLEAR_ARRAY(items); } -void ArraysTestCase::IndexFromEnd() +TEST_CASE("wxDynArray::IndexFromEnd", "[dynarray]") { wxArrayInt a; a.push_back(10); From b113635111d49b723af1e1991dac5688aa07fa8d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 26 Feb 2021 16:36:10 +0100 Subject: [PATCH 05/23] Use CHECK() instead of CPPUNIT_ASSERT_XXX in arrays tests This could be further improved by defining array matchers instead of using the macros, but for now just get rid of the last traces of CppUnit in this file. No real changes. --- tests/arrays/arrays.cpp | 266 ++++++++++++++++++++-------------------- 1 file changed, 133 insertions(+), 133 deletions(-) diff --git a/tests/arrays/arrays.cpp b/tests/arrays/arrays.cpp index 49575dd301..3476bfb62f 100644 --- a/tests/arrays/arrays.cpp +++ b/tests/arrays/arrays.cpp @@ -169,7 +169,7 @@ TEST_CASE("wxArrayString", "[dynarray]") a1.Add(wxT("human")); a1.Add(wxT("alligator")); - CPPUNIT_ASSERT((COMPARE_8_VALUES( a1 , wxT("thermit") , + CHECK((COMPARE_8_VALUES( a1 , wxT("thermit") , wxT("condor") , wxT("lion") , wxT("lion") , @@ -177,11 +177,11 @@ TEST_CASE("wxArrayString", "[dynarray]") wxT("dog") , wxT("human") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 8 ) ); + CHECK( COMPARE_COUNT( a1 , 8 ) ); wxArrayString a2(a1); - CPPUNIT_ASSERT((COMPARE_8_VALUES( a2 , wxT("thermit") , + CHECK((COMPARE_8_VALUES( a2 , wxT("thermit") , wxT("condor") , wxT("lion") , wxT("lion") , @@ -189,11 +189,11 @@ TEST_CASE("wxArrayString", "[dynarray]") wxT("dog") , wxT("human") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 8 ) ); + CHECK( COMPARE_COUNT( a2 , 8 ) ); wxSortedArrayString a3(a1); - CPPUNIT_ASSERT((COMPARE_8_VALUES( a3 , wxT("alligator") , + CHECK((COMPARE_8_VALUES( a3 , wxT("alligator") , wxT("condor") , wxT("dog") , wxT("human") , @@ -201,13 +201,13 @@ TEST_CASE("wxArrayString", "[dynarray]") wxT("lion") , wxT("lion") , wxT("thermit") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a3 , 8 ) ); + CHECK( COMPARE_COUNT( a3 , 8 ) ); wxSortedArrayString a4; for (wxArrayString::iterator it = a1.begin(), en = a1.end(); it != en; ++it) a4.Add(*it); - CPPUNIT_ASSERT((COMPARE_8_VALUES( a4 , wxT("alligator") , + CHECK((COMPARE_8_VALUES( a4 , wxT("alligator") , wxT("condor") , wxT("dog") , wxT("human") , @@ -215,97 +215,97 @@ TEST_CASE("wxArrayString", "[dynarray]") wxT("lion") , wxT("lion") , wxT("thermit") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a4 , 8 ) ); + CHECK( COMPARE_COUNT( a4 , 8 ) ); a1.RemoveAt(2,3); - CPPUNIT_ASSERT((COMPARE_5_VALUES( a1 , wxT("thermit") , + CHECK((COMPARE_5_VALUES( a1 , wxT("thermit") , wxT("condor") , wxT("dog") , wxT("human") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) ); + CHECK( COMPARE_COUNT( a1 , 5 ) ); a2 = a1; - CPPUNIT_ASSERT((COMPARE_5_VALUES( a2 , wxT("thermit") , + CHECK((COMPARE_5_VALUES( a2 , wxT("thermit") , wxT("condor") , wxT("dog") , wxT("human") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a2 , 5 ) ); + CHECK( COMPARE_COUNT( a2 , 5 ) ); a1.Sort(false); - CPPUNIT_ASSERT((COMPARE_5_VALUES( a1 , wxT("alligator") , + CHECK((COMPARE_5_VALUES( a1 , wxT("alligator") , wxT("condor") , wxT("dog") , wxT("human") , wxT("thermit") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) ); + CHECK( COMPARE_COUNT( a1 , 5 ) ); a1.Sort(true); - CPPUNIT_ASSERT((COMPARE_5_VALUES( a1 , wxT("thermit") , + CHECK((COMPARE_5_VALUES( a1 , wxT("thermit") , wxT("human") , wxT("dog") , wxT("condor") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) ); + CHECK( COMPARE_COUNT( a1 , 5 ) ); a1.Sort(&StringLenCompare); - CPPUNIT_ASSERT((COMPARE_5_VALUES( a1 , wxT("dog") , + CHECK((COMPARE_5_VALUES( a1 , wxT("dog") , wxT("human") , wxT("condor") , wxT("thermit") , wxT("alligator") ))); - CPPUNIT_ASSERT( COMPARE_COUNT( a1 , 5 ) ); - CPPUNIT_ASSERT( a1.Index( wxT("dog") ) == 0 ); - CPPUNIT_ASSERT( a1.Index( wxT("human") ) == 1 ); - CPPUNIT_ASSERT( a1.Index( wxT("humann") ) == wxNOT_FOUND ); - CPPUNIT_ASSERT( a1.Index( wxT("condor") ) == 2 ); - CPPUNIT_ASSERT( a1.Index( wxT("thermit") ) == 3 ); - CPPUNIT_ASSERT( a1.Index( wxT("alligator") ) == 4 ); + CHECK( COMPARE_COUNT( a1 , 5 ) ); + CHECK( a1.Index( wxT("dog") ) == 0 ); + CHECK( a1.Index( wxT("human") ) == 1 ); + CHECK( a1.Index( wxT("humann") ) == wxNOT_FOUND ); + CHECK( a1.Index( wxT("condor") ) == 2 ); + CHECK( a1.Index( wxT("thermit") ) == 3 ); + CHECK( a1.Index( wxT("alligator") ) == 4 ); - CPPUNIT_ASSERT( a1.Index( wxT("dog"), /*bCase=*/true, /*fromEnd=*/true ) == 0 ); - CPPUNIT_ASSERT( a1.Index( wxT("human"), /*bCase=*/true, /*fromEnd=*/true ) == 1 ); - CPPUNIT_ASSERT( a1.Index( wxT("humann"), /*bCase=*/true, /*fromEnd=*/true ) == wxNOT_FOUND ); - CPPUNIT_ASSERT( a1.Index( wxT("condor"), /*bCase=*/true, /*fromEnd=*/true ) == 2 ); - CPPUNIT_ASSERT( a1.Index( wxT("thermit"), /*bCase=*/true, /*fromEnd=*/true ) == 3 ); - CPPUNIT_ASSERT( a1.Index( wxT("alligator"), /*bCase=*/true, /*fromEnd=*/true ) == 4 ); + CHECK( a1.Index( wxT("dog"), /*bCase=*/true, /*fromEnd=*/true ) == 0 ); + CHECK( a1.Index( wxT("human"), /*bCase=*/true, /*fromEnd=*/true ) == 1 ); + CHECK( a1.Index( wxT("humann"), /*bCase=*/true, /*fromEnd=*/true ) == wxNOT_FOUND ); + CHECK( a1.Index( wxT("condor"), /*bCase=*/true, /*fromEnd=*/true ) == 2 ); + CHECK( a1.Index( wxT("thermit"), /*bCase=*/true, /*fromEnd=*/true ) == 3 ); + CHECK( a1.Index( wxT("alligator"), /*bCase=*/true, /*fromEnd=*/true ) == 4 ); wxArrayString a5; - CPPUNIT_ASSERT( a5.Add( wxT("x"), 1 ) == 0 ); - CPPUNIT_ASSERT( a5.Add( wxT("a"), 3 ) == 1 ); + CHECK( a5.Add( wxT("x"), 1 ) == 0 ); + CHECK( a5.Add( wxT("a"), 3 ) == 1 ); - CPPUNIT_ASSERT((COMPARE_4_VALUES( a5, wxT("x") , + CHECK((COMPARE_4_VALUES( a5, wxT("x") , wxT("a") , wxT("a") , wxT("a") ))); a5.assign(a1.end(), a1.end()); - CPPUNIT_ASSERT( a5.empty() ); + CHECK( a5.empty() ); a5.assign(a1.begin(), a1.end()); - CPPUNIT_ASSERT( a5 == a1 ); + CHECK( a5 == a1 ); const wxString months[] = { "Jan", "Feb", "Mar" }; a5.assign(months, months + WXSIZEOF(months)); - CPPUNIT_ASSERT_EQUAL( WXSIZEOF(months), a5.size() ); - CPPUNIT_ASSERT((COMPARE_3_VALUES(a5, "Jan", "Feb", "Mar"))); + CHECK( a5.size() == WXSIZEOF(months) ); + CHECK((COMPARE_3_VALUES(a5, "Jan", "Feb", "Mar"))); a5.clear(); - CPPUNIT_ASSERT_EQUAL( 0, a5.size() ); + CHECK( a5.size() == 0 ); a5.resize(7, "Foo"); - CPPUNIT_ASSERT_EQUAL( 7, a5.size() ); - CPPUNIT_ASSERT_EQUAL( "Foo", a5[3] ); + CHECK( a5.size() == 7 ); + CHECK( a5[3] == "Foo" ); a5.resize(3); - CPPUNIT_ASSERT_EQUAL( 3, a5.size() ); - CPPUNIT_ASSERT_EQUAL( "Foo", a5[2] ); + CHECK( a5.size() == 3 ); + CHECK( a5[2] == "Foo" ); wxArrayString a6; a6.Add("Foo"); @@ -317,10 +317,10 @@ TEST_CASE("wxArrayString", "[dynarray]") wxArrayString a7; a7 = a7; - CPPUNIT_ASSERT_EQUAL( 0, a7.size() ); + CHECK( a7.size() == 0 ); a7.Add("Bar"); a7 = a7; - CPPUNIT_ASSERT_EQUAL( 1, a7.size() ); + CHECK( a7.size() == 1 ); wxCLANG_WARNING_RESTORE(self-assign-overloaded) } @@ -330,30 +330,30 @@ TEST_CASE("wxSortedArrayString", "[dynarray]") wxSortedArrayString a; a.Add("d"); a.Add("c"); - CPPUNIT_ASSERT_EQUAL( 0, a.Index("c") ); + CHECK( a.Index("c") == 0 ); a.push_back("b"); a.push_back("a"); - CPPUNIT_ASSERT_EQUAL( 0, a.Index("a") ); + CHECK( a.Index("a") == 0 ); wxSortedArrayString ar(wxStringSortDescending); ar.Add("a"); ar.Add("b"); - CPPUNIT_ASSERT_EQUAL( "b", ar[0] ); - CPPUNIT_ASSERT_EQUAL( "a", ar[1] ); + CHECK( ar[0] == "b" ); + CHECK( ar[1] == "a" ); wxSortedArrayString ad(wxDictionaryStringSortAscending); ad.Add("AB"); ad.Add("a"); ad.Add("Aa"); - CPPUNIT_ASSERT_EQUAL( "a", ad[0] ); - CPPUNIT_ASSERT_EQUAL( "Aa", ad[1] ); - CPPUNIT_ASSERT_EQUAL( 0, ad.Index("a") ); - CPPUNIT_ASSERT_EQUAL( 1, ad.Index("Aa") ); - CPPUNIT_ASSERT_EQUAL( 2, ad.Index("AB") ); - CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("A") ); - CPPUNIT_ASSERT_EQUAL( wxNOT_FOUND, ad.Index("z") ); + CHECK( ad[0] == "a" ); + CHECK( ad[1] == "Aa" ); + CHECK( ad.Index("a") == 0 ); + CHECK( ad.Index("Aa") == 1 ); + CHECK( ad.Index("AB") == 2 ); + CHECK( ad.Index("A") == wxNOT_FOUND ); + CHECK( ad.Index("z") == wxNOT_FOUND ); } TEST_CASE("Arrays::Split", "[dynarray]") @@ -368,7 +368,7 @@ TEST_CASE("Arrays::Split", "[dynarray]") wxArrayString exparr(WXSIZEOF(expected), expected); wxArrayString realarr(wxSplit(str, wxT(','))); - CPPUNIT_ASSERT( exparr == realarr ); + CHECK( exparr == realarr ); } { @@ -381,12 +381,12 @@ TEST_CASE("Arrays::Split", "[dynarray]") // escaping on: wxArrayString exparr(WXSIZEOF(expected), expected); wxArrayString realarr(wxSplit(str, wxT(','), wxT('\\'))); - CPPUNIT_ASSERT( exparr == realarr ); + CHECK( exparr == realarr ); // escaping turned off: wxArrayString exparr2(WXSIZEOF(expected2), expected2); wxArrayString realarr2(wxSplit(str, wxT(','), wxT('\0'))); - CPPUNIT_ASSERT( exparr2 == realarr2 ); + CHECK( exparr2 == realarr2 ); } { @@ -402,12 +402,12 @@ TEST_CASE("Arrays::Split", "[dynarray]") // escaping on: wxArrayString exparr(WXSIZEOF(expected), expected); wxArrayString realarr(wxSplit(str, wxT(','), wxT('\\'))); - CPPUNIT_ASSERT( exparr == realarr ); + CHECK( exparr == realarr ); // escaping turned off: wxArrayString exparr2(WXSIZEOF(expected2), expected2); wxArrayString realarr2(wxSplit(str, wxT(','), wxT('\0'))); - CPPUNIT_ASSERT( exparr2 == realarr2 ); + CHECK( exparr2 == realarr2 ); } } @@ -421,7 +421,7 @@ TEST_CASE("Arrays::Join", "[dynarray]") wxArrayString arrstr(WXSIZEOF(arr), arr); wxString result = wxJoin(arrstr, wxT(',')); - CPPUNIT_ASSERT( expected == result ); + CHECK( expected == result ); } { @@ -432,11 +432,11 @@ TEST_CASE("Arrays::Join", "[dynarray]") // escaping on: wxArrayString arrstr(WXSIZEOF(arr), arr); wxString result = wxJoin(arrstr, wxT(','), wxT('\\')); - CPPUNIT_ASSERT( expected == result ); + CHECK( expected == result ); // escaping turned off: wxString result2 = wxJoin(arrstr, wxT(','), wxT('\0')); - CPPUNIT_ASSERT( expected2 == result2 ); + CHECK( expected2 == result2 ); } { @@ -448,11 +448,11 @@ TEST_CASE("Arrays::Join", "[dynarray]") // escaping on: wxArrayString arrstr(WXSIZEOF(arr), arr); wxString result = wxJoin(arrstr, wxT(','), wxT('\\')); - CPPUNIT_ASSERT( expected == result ); + CHECK( expected == result ); // escaping turned off: wxString result2 = wxJoin(arrstr, wxT(','), wxT('\0')); - CPPUNIT_ASSERT( expected2 == result2 ); + CHECK( expected2 == result2 ); } } @@ -481,7 +481,7 @@ TEST_CASE("Arrays::SplitJoin", "[dynarray]") for (i = 0; i < WXSIZEOF(separators); i++) { wxArrayString arr = wxSplit(str, separators[i]); - CPPUNIT_ASSERT( str == wxJoin(arr, separators[i]) ); + CHECK( str == wxJoin(arr, separators[i]) ); } @@ -498,16 +498,16 @@ TEST_CASE("Arrays::SplitJoin", "[dynarray]") for (i = 0; i < WXSIZEOF(separators); i++) { wxString string = wxJoin(theArr, separators[i]); - CPPUNIT_ASSERT( theArr == wxSplit(string, separators[i]) ); + CHECK( theArr == wxSplit(string, separators[i]) ); } wxArrayString emptyArray; wxString string = wxJoin(emptyArray, wxT(';')); - CPPUNIT_ASSERT( string.empty() ); + CHECK( string.empty() ); - CPPUNIT_ASSERT( wxSplit(string, wxT(';')).empty() ); + CHECK( wxSplit(string, wxT(';')).empty() ); - CPPUNIT_ASSERT_EQUAL( 2, wxSplit(wxT(";"), wxT(';')).size() ); + CHECK( wxSplit(wxT(";"), wxT(';')).size() == 2 ); } TEST_CASE("wxObjArray", "[dynarray]") @@ -516,33 +516,33 @@ TEST_CASE("wxObjArray", "[dynarray]") ArrayBars bars; Bar bar(wxT("first bar in general, second bar in array (two copies!)")); - CPPUNIT_ASSERT_EQUAL( 0, bars.GetCount() ); - CPPUNIT_ASSERT_EQUAL( 1, Bar::GetNumber() ); + CHECK( bars.GetCount() == 0 ); + CHECK( Bar::GetNumber() == 1 ); bars.Add(new Bar(wxT("first bar in array"))); bars.Add(bar, 2); - CPPUNIT_ASSERT_EQUAL( 3, bars.GetCount() ); - CPPUNIT_ASSERT_EQUAL( 4, Bar::GetNumber() ); + CHECK( bars.GetCount() == 3 ); + CHECK( Bar::GetNumber() == 4 ); bars.RemoveAt(1, bars.GetCount() - 1); - CPPUNIT_ASSERT_EQUAL( 1, bars.GetCount() ); - CPPUNIT_ASSERT_EQUAL( 2, Bar::GetNumber() ); + CHECK( bars.GetCount() == 1 ); + CHECK( Bar::GetNumber() == 2 ); bars.Empty(); - CPPUNIT_ASSERT_EQUAL( 0, bars.GetCount() ); - CPPUNIT_ASSERT_EQUAL( 1, Bar::GetNumber() ); + CHECK( bars.GetCount() == 0 ); + CHECK( Bar::GetNumber() == 1 ); } - CPPUNIT_ASSERT_EQUAL( 0, Bar::GetNumber() ); + CHECK( Bar::GetNumber() == 0 ); } TEST_CASE("wxObjArrayPtr", "[dynarray]") { // Just check that instantiating this class compiles. ArrayBarPtrs barptrs; - CPPUNIT_ASSERT_EQUAL( 0, barptrs.size() ); + CHECK( barptrs.size() == 0 ); } #define TestArrayOf(name) \ @@ -555,18 +555,18 @@ TEST_CASE("wxDynArray::" #name, "[dynarray]") \ a.Add(5,3); \ a.Add(3,4); \ \ - CPPUNIT_ASSERT((COMPARE_10_VALUES(a,1,17,17,5,5,5,3,3,3,3))); \ - CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \ + CHECK((COMPARE_10_VALUES(a,1,17,17,5,5,5,3,3,3,3))); \ + CHECK( COMPARE_COUNT( a , 10 ) ); \ \ a.Sort(name ## Compare); \ \ - CPPUNIT_ASSERT((COMPARE_10_VALUES(a,1,3,3,3,3,5,5,5,17,17))); \ - CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \ + CHECK((COMPARE_10_VALUES(a,1,3,3,3,3,5,5,5,17,17))); \ + CHECK( COMPARE_COUNT( a , 10 ) ); \ \ a.Sort(name ## RevCompare); \ \ - CPPUNIT_ASSERT((COMPARE_10_VALUES(a,17,17,5,5,5,3,3,3,3,1))); \ - CPPUNIT_ASSERT( COMPARE_COUNT( a , 10 ) ); \ + CHECK((COMPARE_10_VALUES(a,17,17,5,5,5,3,3,3,3,1))); \ + CHECK( COMPARE_COUNT( a , 10 ) ); \ \ wxSortedArray##name b; \ \ @@ -575,15 +575,15 @@ TEST_CASE("wxDynArray::" #name, "[dynarray]") \ b.Add(5); \ b.Add(3); \ \ - CPPUNIT_ASSERT((COMPARE_4_VALUES(b,1,3,5,17))); \ - CPPUNIT_ASSERT( COMPARE_COUNT( b , 4 ) ); \ - CPPUNIT_ASSERT( b.Index( 0 ) == wxNOT_FOUND ); \ - CPPUNIT_ASSERT( b.Index( 1 ) == 0 ); \ - CPPUNIT_ASSERT( b.Index( 3 ) == 1 ); \ - CPPUNIT_ASSERT( b.Index( 4 ) == wxNOT_FOUND ); \ - CPPUNIT_ASSERT( b.Index( 5 ) == 2 ); \ - CPPUNIT_ASSERT( b.Index( 6 ) == wxNOT_FOUND ); \ - CPPUNIT_ASSERT( b.Index( 17 ) == 3 ); \ + CHECK((COMPARE_4_VALUES(b,1,3,5,17))); \ + CHECK( COMPARE_COUNT( b , 4 ) ); \ + CHECK( b.Index( 0 ) == wxNOT_FOUND ); \ + CHECK( b.Index( 1 ) == 0 ); \ + CHECK( b.Index( 3 ) == 1 ); \ + CHECK( b.Index( 4 ) == wxNOT_FOUND ); \ + CHECK( b.Index( 5 ) == 2 ); \ + CHECK( b.Index( 6 ) == wxNOT_FOUND ); \ + CHECK( b.Index( 17 ) == 3 ); \ } TestArrayOf(UShort) @@ -597,13 +597,13 @@ TEST_CASE("wxDynArray::Alloc", "[dynarray]") wxArrayInt a; a.Add(17); a.Add(9); - CPPUNIT_ASSERT_EQUAL( 2, a.GetCount() ); + CHECK( a.GetCount() == 2 ); a.Alloc(1000); - CPPUNIT_ASSERT_EQUAL( 2, a.GetCount() ); - CPPUNIT_ASSERT_EQUAL( 17, a[0] ); - CPPUNIT_ASSERT_EQUAL( 9, a[1] ); + CHECK( a.GetCount() == 2 ); + CHECK( a[0] == 17 ); + CHECK( a[1] == 9 ); } TEST_CASE("wxDynArray::Clear", "[dynarray]") @@ -611,14 +611,14 @@ TEST_CASE("wxDynArray::Clear", "[dynarray]") ItemPtrArray items; WX_CLEAR_ARRAY(items); - CPPUNIT_ASSERT_EQUAL( 0, items.size() ); + CHECK( items.size() == 0 ); items.push_back(new Item(17)); items.push_back(new Item(71)); - CPPUNIT_ASSERT_EQUAL( 2, items.size() ); + CHECK( items.size() == 2 ); WX_CLEAR_ARRAY(items); - CPPUNIT_ASSERT_EQUAL( 0, items.size() ); + CHECK( items.size() == 0 ); } namespace @@ -629,25 +629,25 @@ void DoTestSwap(T v1, T v2, T v3) { A a1, a2; a1.swap(a2); - CPPUNIT_ASSERT( a1.empty() ); - CPPUNIT_ASSERT( a2.empty() ); + CHECK( a1.empty() ); + CHECK( a2.empty() ); a1.push_back(v1); a1.swap(a2); - CPPUNIT_ASSERT( a1.empty() ); - CPPUNIT_ASSERT_EQUAL( 1, a2.size() ); + CHECK( a1.empty() ); + CHECK( a2.size() == 1 ); a1.push_back(v2); a1.push_back(v3); a2.swap(a1); - CPPUNIT_ASSERT_EQUAL( 1, a1.size() ); - CPPUNIT_ASSERT_EQUAL( 2, a2.size() ); - CPPUNIT_ASSERT_EQUAL( v1, a1[0] ); - CPPUNIT_ASSERT_EQUAL( v3, a2[1] ); + CHECK( a1.size() == 1 ); + CHECK( a2.size() == 2 ); + CHECK( a1[0] == v1 ); + CHECK( a2[1] == v3 ); a1.swap(a2); - CPPUNIT_ASSERT_EQUAL( 2, a1.size() ); - CPPUNIT_ASSERT_EQUAL( 1, a2.size() ); + CHECK( a1.size() == 2 ); + CHECK( a2.size() == 1 ); } } // anonymous namespace @@ -671,35 +671,35 @@ TEST_CASE("wxDynArray::TestSTL", "[dynarray]") for ( i = 0; i < COUNT; ++i ) list1.push_back(i); - CPPUNIT_ASSERT( list1.capacity() >= (size_t)COUNT ); - CPPUNIT_ASSERT_EQUAL( COUNT, list1.size() ); + CHECK( list1.capacity() >= (size_t)COUNT ); + CHECK( list1.size() == COUNT ); for ( it = list1.begin(), en = list1.end(), i = 0; it != en; ++it, ++i ) { - CPPUNIT_ASSERT( *it == i ); + CHECK( *it == i ); } - CPPUNIT_ASSERT_EQUAL( COUNT, i ); + CHECK( i == COUNT ); for ( rit = list1.rbegin(), ren = list1.rend(), i = COUNT; rit != ren; ++rit, --i ) { - CPPUNIT_ASSERT( *rit == i-1 ); + CHECK( *rit == i-1 ); } - CPPUNIT_ASSERT_EQUAL( 0, i ); + CHECK( i == 0 ); - CPPUNIT_ASSERT( *list1.rbegin() == *(list1.end()-1) ); - CPPUNIT_ASSERT( *list1.begin() == *(list1.rend()-1) ); + CHECK( *list1.rbegin() == *(list1.end()-1) ); + CHECK( *list1.begin() == *(list1.rend()-1) ); it = list1.begin()+1; rit = list1.rbegin()+1; - CPPUNIT_ASSERT( *list1.begin() == *(it-1) ); - CPPUNIT_ASSERT( *list1.rbegin() == *(rit-1) ); + CHECK( *list1.begin() == *(it-1) ); + CHECK( *list1.rbegin() == *(rit-1) ); - CPPUNIT_ASSERT( list1.front() == 0 ); - CPPUNIT_ASSERT( list1.back() == COUNT - 1 ); + CHECK( list1.front() == 0 ); + CHECK( list1.back() == COUNT - 1 ); list1.erase(list1.begin()); list1.erase(list1.end()-1); @@ -707,14 +707,14 @@ TEST_CASE("wxDynArray::TestSTL", "[dynarray]") for ( it = list1.begin(), en = list1.end(), i = 1; it != en; ++it, ++i ) { - CPPUNIT_ASSERT( *it == i ); + CHECK( *it == i ); } ItemPtrArray items; items.push_back(new Item(17)); - CPPUNIT_ASSERT_EQUAL( 17, (*(items.rbegin()))->n ); - CPPUNIT_ASSERT_EQUAL( 17, (**items.begin()).n ); + CHECK( (*(items.rbegin()))->n == 17 ); + CHECK( (**items.begin()).n == 17 ); WX_CLEAR_ARRAY(items); } @@ -725,12 +725,12 @@ TEST_CASE("wxDynArray::IndexFromEnd", "[dynarray]") a.push_back(1); a.push_back(42); - CPPUNIT_ASSERT_EQUAL( 0, a.Index(10) ); - CPPUNIT_ASSERT_EQUAL( 1, a.Index(1) ); - CPPUNIT_ASSERT_EQUAL( 2, a.Index(42) ); - CPPUNIT_ASSERT_EQUAL( 0, a.Index(10, /*bFromEnd=*/true) ); - CPPUNIT_ASSERT_EQUAL( 1, a.Index(1, /*bFromEnd=*/true) ); - CPPUNIT_ASSERT_EQUAL( 2, a.Index(42, /*bFromEnd=*/true) ); + CHECK( a.Index(10) == 0 ); + CHECK( a.Index(1) == 1 ); + CHECK( a.Index(42) == 2 ); + CHECK( a.Index(10, /*bFromEnd=*/true) == 0 ); + CHECK( a.Index( 1, /*bFromEnd=*/true) == 1 ); + CHECK( a.Index(42, /*bFromEnd=*/true) == 2 ); } From 063dd3e8525829b1e775a763f517d50f9f3e2b79 Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Wed, 24 Feb 2021 19:20:41 +0000 Subject: [PATCH 06/23] Remove hardcoded max width from STC autocomplete listbox The Scintilla engine will automatically truncate lines in the autocomplete listbox based on the call to AutoCompSetMaxWidth(). It is not good to do it in the wx implementation code as well, since then the meaning of AutoCompSetMaxWidth(0) (e.g. no truncation) is not valid and the list items will be truncated anyway. Closes https://github.com/wxWidgets/wxWidgets/pull/2250 --- src/stc/PlatWX.cpp | 34 +++++++++++++++++++++++++++++----- src/stc/PlatWX.h | 5 +++++ src/stc/ScintillaWX.cpp | 7 +++++-- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index a01287d4c3..84012f84e3 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -2647,6 +2647,7 @@ public: // Setters void SetContainerBorderSize(int); + void SetMaxListBoxWidth(int); // ListBoxImpl implementation virtual void SetListBoxFont(Font &font); @@ -2698,6 +2699,7 @@ protected: int m_textHeight; int m_itemHeight; int m_textTopGap; + int m_maxBoxWidth; // 0 means no max width // These drawing parameters are set internally and can be changed if needed // to better match the appearance of a list box on a specific platform. @@ -2711,7 +2713,7 @@ wxSTCListBox::wxSTCListBox(wxWindow* parent, wxSTCListBoxVisualData* v, int ht) m_visualData(v), m_maxStrWidth(0), m_currentRow(wxNOT_FOUND), m_doubleClickAction(NULL), m_doubleClickActionData(NULL), m_aveCharWidth(8), m_textHeight(ht), m_itemHeight(ht), - m_textTopGap(0) + m_textTopGap(0), m_maxBoxWidth(350) { wxVListBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, "AutoCompListBox"); @@ -2757,6 +2759,11 @@ void wxSTCListBox::SetContainerBorderSize(int s) m_borderSize = s; } +void wxSTCListBox::SetMaxListBoxWidth(int maxWidth) +{ + m_maxBoxWidth = maxWidth; +} + void wxSTCListBox::SetListBoxFont(Font &font) { SetFont(*((wxFont*)font.GetID())); @@ -2776,10 +2783,14 @@ PRectangle wxSTCListBox::GetDesiredRect() const int maxh ; // give it a default if there are no lines, and/or add a bit more - if (maxw == 0) maxw = 100; + if ( maxw == 0 ) + maxw = 100; + maxw += TextBoxFromClientEdge() + m_textBoxToTextGap + m_aveCharWidth * 3; - if (maxw > 350) - maxw = 350; + + // m_maxBoxWidth == 0 or negative means no maximum + if ( ( m_maxBoxWidth > 0 ) && ( maxw > m_maxBoxWidth ) ) + maxw = m_maxBoxWidth; // estimate a desired height const int count = Length(); @@ -3271,7 +3282,7 @@ void wxSTCListBoxWin::OnPaint(wxPaintEvent& WXUNUSED(evt)) //---------------------------------------------------------------------- ListBoxImpl::ListBoxImpl() - :m_listBox(NULL), m_visualData(new wxSTCListBoxVisualData(5)) + :m_listBox(NULL), m_visualData(new wxSTCListBoxVisualData(5)), m_listBoxWidth(-1) { } @@ -3290,6 +3301,19 @@ void ListBoxImpl::Create(Window &parent, int WXUNUSED(ctrlID), bool WXUNUSED(unicodeMode_), int technology_) { wid = new wxSTCListBoxWin(GETWIN(parent.GetID()), &m_listBox, m_visualData, lineHeight_, technology_); + + if ( m_listBoxWidth >= 0 ) + m_listBox->SetMaxListBoxWidth(m_listBoxWidth); +} + + +void ListBoxImpl::SetMaxListBoxWidth(int width) { + // Store the setting for future list box creations + m_listBoxWidth = width; + + // Update the listbox if it currently exists, but allow this to be called before it is created + if ( m_listBox ) + m_listBox->SetMaxListBoxWidth(m_listBoxWidth); } diff --git a/src/stc/PlatWX.h b/src/stc/PlatWX.h index bdaf7fef4b..c613607fb4 100644 --- a/src/stc/PlatWX.h +++ b/src/stc/PlatWX.h @@ -23,6 +23,10 @@ private: wxSTCListBox* m_listBox; wxSTCListBoxVisualData* m_visualData; + // Allow the implementation to control the width of the underlying listbox. + // If this is negative, then the underlying listbox retains control over the max width. + int m_listBoxWidth; + public: ListBoxImpl(); ~ListBoxImpl(); @@ -30,6 +34,7 @@ public: virtual void SetFont(Font &font) wxOVERRIDE; virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_, int technology_) wxOVERRIDE; + void SetMaxListBoxWidth(int width); virtual void SetAverageCharWidth(int width) wxOVERRIDE; virtual void SetVisibleRows(int rows) wxOVERRIDE; virtual int GetVisibleRows() const wxOVERRIDE; diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 5537bebb05..ef06279ebd 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -292,8 +292,11 @@ void ScintillaWX::Initialise() { kmap.AssignCmdKey(SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND); #endif // __WXMAC__ - static_cast(ac.lb)->SetListInfo(&listType, &(ac.posStart), - &(ac.startLen)); + ListBoxImpl* autoCompleteLB = static_cast( ac.lb ); + + // Let the Scintilla autocomplete engine determine the max size for the listbox + autoCompleteLB->SetMaxListBoxWidth( 0 ); + autoCompleteLB->SetListInfo( &listType, &(ac.posStart), &(ac.startLen) ); } From 9a29ea6e6390d46ce24d149d90eb9ba73f7e070c Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 27 Feb 2021 16:36:10 +0100 Subject: [PATCH 07/23] Fix setting wxBU_EXACTFIT style for wxButton under wxGTK2 The way wxBU_EXACTFIT is implemented in commit c1bb80987f ("Improve implementation of wxBU_EXACTFIT style for wxButton under wxGTK2", 2020-04-12) is too intrusive and disrupts button's appearance in some themes. It should work better with themes if we reduce inner border in a more GTK-compliant way by applying a dedicated GTK style to the button. Closes #19081. --- include/wx/gtk/button.h | 6 ++++++ src/gtk/button.cpp | 24 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/wx/gtk/button.h b/include/wx/gtk/button.h index b8e8128d71..e6fb1b57d3 100644 --- a/include/wx/gtk/button.h +++ b/include/wx/gtk/button.h @@ -67,6 +67,12 @@ private: // Return the GtkLabel used by this button. GtkLabel *GTKGetLabel() const; +#ifndef __WXGTK3__ + // To mark if special GTK style for buttons with wxBU_EXACTFIT flag + // was already defined. + static bool m_exactFitStyleDefined; +#endif // !__WXGTK3__ + wxDECLARE_DYNAMIC_CLASS(wxButton); }; diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp index 267bd0d61b..194c205ef4 100644 --- a/src/gtk/button.cpp +++ b/src/gtk/button.cpp @@ -70,6 +70,10 @@ wxgtk_button_style_set_callback(GtkWidget* widget, GtkStyle*, wxButton* win) // wxButton //----------------------------------------------------------------------------- +#ifndef __WXGTK3__ +bool wxButton::m_exactFitStyleDefined = false; +#endif // !__WXGTK3__ + bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString &label, @@ -141,7 +145,20 @@ bool wxButton::Create(wxWindow *parent, #ifdef __WXGTK3__ GTKApplyCssStyle("* { padding:0 }"); #else - GTKApplyWidgetStyle(true); // To enforce call to DoApplyWidgetStyle() + // Define a special button style without inner border + // if it's not yet done. + if ( !m_exactFitStyleDefined ) + { + gtk_rc_parse_string( + "style \"wxButton_wxBU_EXACTFIT_style\"\n" + "{ GtkButton::inner-border = { 0, 0, 0, 0 } }\n" + "widget \"*wxButton_wxBU_EXACTFIT*\" style \"wxButton_wxBU_EXACTFIT_style\"\n" + ); + m_exactFitStyleDefined = true; + } + + // Assign the button to the GTK style without inner border. + gtk_widget_set_name(m_widget, "wxButton_wxBU_EXACTFIT"); #endif // __WXGTK3__ / !__WXGTK3__ } @@ -312,11 +329,6 @@ GtkLabel *wxButton::GTKGetLabel() const void wxButton::DoApplyWidgetStyle(GtkRcStyle *style) { - if ( style && HasFlag(wxBU_EXACTFIT) ) - { - style->xthickness = 0; - style->ythickness = 0; - } GTKApplyStyle(m_widget, style); GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget)); GTKApplyStyle(child, style); From 04ea7b552a2a2b07c0ea8d1cb6b49e4487d5714b Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 27 Feb 2021 17:10:03 +0100 Subject: [PATCH 08/23] Fix wxBitmapButon used as wxPG editor button under wxGTK2 wxBitmapButton without inner border should work better with themes if we reduce inner border in a more GTK-compliant way by applying a dedicated GTK style to the button. --- src/propgrid/editors.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index 586714235c..5bcfba7110 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -2162,28 +2162,36 @@ public: #if defined(__WXGTK3__) GTKApplyCssStyle("*{ padding:0 }"); #else -#if !defined( __WXGTK127__ ) - GTKApplyWidgetStyle(true); // To enforce call to DoApplyWidgetStyle() -#endif + // Define a special button style without inner border + // if it's not yet done. + if ( !m_exactFitStyleDefined ) + { + gtk_rc_parse_string( + "style \"wxPGEditorBitmapButton_style\"\n" + "{ GtkButton::inner-border = { 0, 0, 0, 0 } }\n" + "widget \"*wxPGEditorBitmapButton*\" style \"wxPGEditorBitmapButton_style\"\n" + ); + m_exactFitStyleDefined = true; + } + + // Assign the button to the GTK style without inner border. + gtk_widget_set_name(m_widget, "wxPGEditorBitmapButton"); #endif } virtual ~wxPGEditorBitmapButton() { } -protected: - virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE - { - if ( style ) - { -#if !defined( __WXGTK127__ ) - style->xthickness = 0; - style->ythickness = 0; -#endif - } - wxBitmapButton::DoApplyWidgetStyle(style); - } +private: +#ifndef __WXGTK3__ + // To mark if special GTK style was already defined. + static bool m_exactFitStyleDefined; +#endif // !__WXGTK3__ }; +#ifndef __WXGTK3__ +bool wxPGEditorBitmapButton::m_exactFitStyleDefined = false; +#endif // !__WXGTK3__ + #else // !__WXGTK__ typedef wxBitmapButton wxPGEditorBitmapButton; From f6a53b59b2cfaa8606bef488080db0515d5d85e0 Mon Sep 17 00:00:00 2001 From: Scott Talbert Date: Sat, 27 Feb 2021 11:48:49 -0500 Subject: [PATCH 09/23] Fix regression in wxGetKeyState() on GTK3 w/ X11 wxGetKeyStateGTK() is intended to be used only with non-X11 GTK backends. wxGetKeyStateX11() should still be used on GTK3 w/ X11 as the GTK variant does not provide all key states. --- src/unix/utilsx11.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/unix/utilsx11.cpp b/src/unix/utilsx11.cpp index 3aa9c0a53c..aabd8912ca 100644 --- a/src/unix/utilsx11.cpp +++ b/src/unix/utilsx11.cpp @@ -2550,7 +2550,6 @@ int wxUnicodeCharXToWX(WXKeySym keySym) // check current state of a key // ---------------------------------------------------------------------------- -#ifndef wxHAS_GETKEYSTATE_GTK static bool wxGetKeyStateX11(wxKeyCode key) { wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != @@ -2595,7 +2594,6 @@ static bool wxGetKeyStateX11(wxKeyCode key) XQueryKeymap(pDisplay, key_vector); return (key_vector[keyCode >> 3] & (1 << (keyCode & 7))) != 0; } -#endif #endif // !defined(__WXGTK__) || defined(GDK_WINDOWING_X11) @@ -2643,17 +2641,20 @@ static bool wxGetKeyStateGTK(wxKeyCode key) bool wxGetKeyState(wxKeyCode key) { #ifdef wxHAS_GETKEYSTATE_GTK - bool ret = false; GdkDisplay* display = gdk_window_get_display(wxGetTopLevelGDK()); const char* name = g_type_name(G_TYPE_FROM_INSTANCE(display)); if (strcmp(name, "GdkX11Display") != 0) { - ret = wxGetKeyStateGTK(key); + return wxGetKeyStateGTK(key); } - return ret; -#else - return wxGetKeyStateX11(key); #endif // GTK+ 3.4+ + +#if !defined(__WXGTK__) || \ + (!defined(__WXGTK20__) || defined(GDK_WINDOWING_X11)) + return wxGetKeyStateX11(key); +#endif + + return false; } // ---------------------------------------------------------------------------- From a75aa7826301a06c77c71b9f4bf1dc21f0927b98 Mon Sep 17 00:00:00 2001 From: PB Date: Sun, 28 Feb 2021 12:10:30 +0100 Subject: [PATCH 10/23] Fix dragging file in DnD sample At least on Microsoft Windows, it is possible to start dragging an unselected wxTreeCtrl item. Therefore, in wxEVT_TREE_BEGIN_DRAG handler do not use the path that is currently selected in the control but the one that is actually being dragged. Closes https://github.com/wxWidgets/wxWidgets/pull/2258 --- samples/dnd/dnd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/dnd/dnd.cpp b/samples/dnd/dnd.cpp index 2f8e20ff88..f33945a595 100644 --- a/samples/dnd/dnd.cpp +++ b/samples/dnd/dnd.cpp @@ -1270,10 +1270,10 @@ void DnDFrame::OnUsePrimary(wxCommandEvent& event) #if wxUSE_DRAG_AND_DROP -void DnDFrame::OnBeginDrag(wxTreeEvent& WXUNUSED(event)) +void DnDFrame::OnBeginDrag(wxTreeEvent& event) { wxFileDataObject data; - data.AddFile(m_ctrlDir->GetPath()); + data.AddFile(m_ctrlDir->GetPath(event.GetItem())); wxDropSource dragSource(this); dragSource.SetData(data); From df20e5ec76a61a12a8b12a31ff6db21226fcd8f0 Mon Sep 17 00:00:00 2001 From: nns52k <58716684+nns52k@users.noreply.github.com> Date: Mon, 18 Jan 2021 15:42:11 +0800 Subject: [PATCH 11/23] Fix case of WebView2.h in the #inclue directive Using the correct case is important when using case-sensitive file systems as when cross-compiling, for example. --- include/wx/msw/private/webview_edge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/msw/private/webview_edge.h b/include/wx/msw/private/webview_edge.h index f78d984395..146d87d34c 100644 --- a/include/wx/msw/private/webview_edge.h +++ b/include/wx/msw/private/webview_edge.h @@ -13,7 +13,7 @@ #include "wx/dynlib.h" #include "wx/msw/private/comptr.h" -#include +#include #ifndef __ICoreWebView2Environment_INTERFACE_DEFINED__ #error "WebView2 SDK version 0.9.430 or newer is required" From b465a95dcc9d92d4ee3a4bf7a58287ad0c98d251 Mon Sep 17 00:00:00 2001 From: nns52k <58716684+nns52k@users.noreply.github.com> Date: Sun, 17 Jan 2021 23:35:51 +0800 Subject: [PATCH 12/23] Make it possible to compile wxWebView Edge backend with gcc Remove the requirement to include wrl/event.h so that GNU C++ (maybe Clang C++ as well) can compile this file without error. --- src/msw/webview_edge.cpp | 121 ++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 22 deletions(-) diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 355d384e31..603d7a8387 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -26,10 +26,87 @@ #include "wx/msw/private/cotaskmemptr.h" #include "wx/msw/private/webview_edge.h" -#include -#include +#include +#include -using namespace Microsoft::WRL; +template +class CInvokable : public baseT +{ +public: + CInvokable() : m_nRefCount(0) {} + virtual ~CInvokable() {} + // IUnknown methods + HRESULT QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override + { + /** + * WebView2 Runtime apparently doesn't use this method, so it doesn't + * matter how we implement this. On the other hand, this method must be + * implemented to make this invokable type a concrete class instead of a + * abstract one. + */ + *ppvObj = NULL; + return E_NOINTERFACE; + } + ULONG AddRef(void) override { + return ++m_nRefCount; + } + ULONG Release(void) override { + size_t ret = --m_nRefCount; + if (ret == 0) + delete this; + return ret; + } +private: + std::atomic m_nRefCount; +}; +template +class CInvokableLambda : public CInvokable +{ +public: + CInvokableLambda(std::function lambda) + : m_lambda(lambda) { + } + // baseT method + HRESULT Invoke(argTs ...args) override { + return m_lambda(args...); + } +private: + std::function m_lambda; +}; +template +class CInvokableMethod : public CInvokable +{ +public: + CInvokableMethod(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) + : m_ctx(ctx), m_mthd(mthd) { + } + // baseT method + HRESULT Invoke(argTs ...args) override { + return (m_ctx->*m_mthd)(args...); + } +private: + contextT *m_ctx; + HRESULT (contextT::*m_mthd)(argTs...); +}; +// the function templates to generate concrete classes from above class templates +template < + typename baseT, typename lambdaT, // base type & lambda type + typename LT, typename ...argTs // for capturing argument types of lambda +> +baseT *callback_impl(lambdaT&& lambda, HRESULT (LT::*)(argTs...) const) +{ + return new CInvokableLambda(lambda); +} +template +baseT *callback(lambdaT&& lambda) +{ + return callback_impl(std::move(lambda), &lambdaT::operator()); +} +template +baseT *callback(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) +{ + return new CInvokableMethod(ctx, mthd); +} wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView); @@ -93,8 +170,8 @@ bool wxWebViewEdgeImpl::Create() ms_browserExecutableDir.wc_str(), userDataPath.wc_str(), nullptr, - Callback(this, - &wxWebViewEdgeImpl::OnEnvironmentCreated).Get()); + callback(this, + &wxWebViewEdgeImpl::OnEnvironmentCreated)); if (FAILED(hr)) { wxLogApiError("CreateWebView2EnvironmentWithOptions", hr); @@ -110,8 +187,8 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated( environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment)); m_webViewEnvironment->CreateCoreWebView2Controller( m_ctrl->GetHWND(), - Callback( - this, &wxWebViewEdgeImpl::OnWebViewCreated).Get()); + callback( + this, &wxWebViewEdgeImpl::OnWebViewCreated)); return S_OK; } @@ -241,8 +318,8 @@ HRESULT wxWebViewEdgeImpl::OnNavigationCompleted(ICoreWebView2* WXUNUSED(sender) } else { - if (m_historyEnabled && !m_historyLoadingFromList && - (uri == m_ctrl->GetCurrentURL()) || + if ((m_historyEnabled && !m_historyLoadingFromList && + (uri == m_ctrl->GetCurrentURL())) || (m_ctrl->GetCurrentURL().substr(0, 4) == "file" && wxFileName::URLToFileName(m_ctrl->GetCurrentURL()).GetFullPath() == uri)) { @@ -340,28 +417,28 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control // Connect and handle the various WebView events m_webView->add_NavigationStarting( - Callback( - this, &wxWebViewEdgeImpl::OnNavigationStarting).Get(), + callback( + this, &wxWebViewEdgeImpl::OnNavigationStarting), &m_navigationStartingToken); m_webView->add_SourceChanged( Callback( this, &wxWebViewEdgeImpl::OnSourceChanged).Get(), &m_sourceChangedToken); m_webView->add_NavigationCompleted( - Callback( - this, &wxWebViewEdgeImpl::OnNavigationCompleted).Get(), + callback( + this, &wxWebViewEdgeImpl::OnNavigationCompleted), &m_navigationCompletedToken); m_webView->add_NewWindowRequested( - Callback( - this, &wxWebViewEdgeImpl::OnNewWindowRequested).Get(), + callback( + this, &wxWebViewEdgeImpl::OnNewWindowRequested), &m_newWindowRequestedToken); m_webView->add_DocumentTitleChanged( - Callback( - this, &wxWebViewEdgeImpl::OnDocumentTitleChanged).Get(), + callback( + this, &wxWebViewEdgeImpl::OnDocumentTitleChanged), &m_documentTitleChangedToken); m_webView->add_ContentLoading( - Callback( - this, &wxWebViewEdgeImpl::OnContentLoading).Get(), + callback( + this, &wxWebViewEdgeImpl::OnContentLoading), &m_contentLoadingToken); m_webView->add_ContainsFullScreenElementChanged( Callback( @@ -709,7 +786,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) bool scriptExecuted = false; // Start script execution - HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), Callback( + HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), callback( [&scriptExecuted, &executionResult, output](HRESULT error, PCWSTR result) -> HRESULT { // Handle script execution callback @@ -724,7 +801,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) scriptExecuted = true; return S_OK; - }).Get()); + })); // Wait for script exection while (!scriptExecuted) @@ -772,7 +849,7 @@ bool wxWebViewEdge::RunScript(const wxString& javascript, wxString* output) cons return true; } -void wxWebViewEdge::RegisterHandler(wxSharedPtr handler) +void wxWebViewEdge::RegisterHandler(wxSharedPtr WXUNUSED(handler)) { // TODO: could maybe be implemented via IWebView2WebView5::add_WebResourceRequested wxLogDebug("Registering handlers is not supported"); From 84b19a0ce03bc2442a7479738e1cdab68cc1ae87 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Wed, 27 Jan 2021 22:34:15 +0100 Subject: [PATCH 13/23] Use the same function signature as the WebView2 SDK --- include/wx/msw/private/comptr.h | 5 ++++ src/msw/webview_edge.cpp | 44 ++++++++++++++++----------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/wx/msw/private/comptr.h b/include/wx/msw/private/comptr.h index 2b21cfa82e..db8c9bcf95 100644 --- a/include/wx/msw/private/comptr.h +++ b/include/wx/msw/private/comptr.h @@ -100,6 +100,11 @@ public: return m_ptr; } + T* Get() const + { + return m_ptr; + } + bool operator<(T* ptr) const { return get() < ptr; diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 603d7a8387..866c2b3eb0 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -93,19 +93,19 @@ template < typename baseT, typename lambdaT, // base type & lambda type typename LT, typename ...argTs // for capturing argument types of lambda > -baseT *callback_impl(lambdaT&& lambda, HRESULT (LT::*)(argTs...) const) +wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT (LT::*)(argTs...) const) { - return new CInvokableLambda(lambda); + return wxCOMPtr(new CInvokableLambda(lambda)); } template -baseT *callback(lambdaT&& lambda) +wxCOMPtr Callback(lambdaT&& lambda) { - return callback_impl(std::move(lambda), &lambdaT::operator()); + return Callback_impl(std::move(lambda), &lambdaT::operator()); } template -baseT *callback(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) +wxCOMPtr Callback(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) { - return new CInvokableMethod(ctx, mthd); + return wxCOMPtr(new CInvokableMethod(ctx, mthd)); } wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView); @@ -170,8 +170,8 @@ bool wxWebViewEdgeImpl::Create() ms_browserExecutableDir.wc_str(), userDataPath.wc_str(), nullptr, - callback(this, - &wxWebViewEdgeImpl::OnEnvironmentCreated)); + Callback(this, + &wxWebViewEdgeImpl::OnEnvironmentCreated).Get()); if (FAILED(hr)) { wxLogApiError("CreateWebView2EnvironmentWithOptions", hr); @@ -187,8 +187,8 @@ HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated( environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment)); m_webViewEnvironment->CreateCoreWebView2Controller( m_ctrl->GetHWND(), - callback( - this, &wxWebViewEdgeImpl::OnWebViewCreated)); + Callback( + this, &wxWebViewEdgeImpl::OnWebViewCreated).Get()); return S_OK; } @@ -417,28 +417,28 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control // Connect and handle the various WebView events m_webView->add_NavigationStarting( - callback( - this, &wxWebViewEdgeImpl::OnNavigationStarting), + Callback( + this, &wxWebViewEdgeImpl::OnNavigationStarting).Get(), &m_navigationStartingToken); m_webView->add_SourceChanged( Callback( this, &wxWebViewEdgeImpl::OnSourceChanged).Get(), &m_sourceChangedToken); m_webView->add_NavigationCompleted( - callback( - this, &wxWebViewEdgeImpl::OnNavigationCompleted), + Callback( + this, &wxWebViewEdgeImpl::OnNavigationCompleted).Get(), &m_navigationCompletedToken); m_webView->add_NewWindowRequested( - callback( - this, &wxWebViewEdgeImpl::OnNewWindowRequested), + Callback( + this, &wxWebViewEdgeImpl::OnNewWindowRequested).Get(), &m_newWindowRequestedToken); m_webView->add_DocumentTitleChanged( - callback( - this, &wxWebViewEdgeImpl::OnDocumentTitleChanged), + Callback( + this, &wxWebViewEdgeImpl::OnDocumentTitleChanged).Get(), &m_documentTitleChangedToken); m_webView->add_ContentLoading( - callback( - this, &wxWebViewEdgeImpl::OnContentLoading), + Callback( + this, &wxWebViewEdgeImpl::OnContentLoading).Get(), &m_contentLoadingToken); m_webView->add_ContainsFullScreenElementChanged( Callback( @@ -786,7 +786,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) bool scriptExecuted = false; // Start script execution - HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), callback( + HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), Callback( [&scriptExecuted, &executionResult, output](HRESULT error, PCWSTR result) -> HRESULT { // Handle script execution callback @@ -801,7 +801,7 @@ bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) scriptExecuted = true; return S_OK; - })); + }).Get()); // Wait for script exection while (!scriptExecuted) From ad1219d0a201ceed31472148a115ea99172848bd Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Wed, 27 Jan 2021 22:37:57 +0100 Subject: [PATCH 14/23] Fix building with MSVC 32 bit --- src/msw/webview_edge.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 866c2b3eb0..c4cbe16427 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -36,7 +36,7 @@ public: CInvokable() : m_nRefCount(0) {} virtual ~CInvokable() {} // IUnknown methods - HRESULT QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override { /** * WebView2 Runtime apparently doesn't use this method, so it doesn't @@ -47,10 +47,10 @@ public: *ppvObj = NULL; return E_NOINTERFACE; } - ULONG AddRef(void) override { + ULONG STDMETHODCALLTYPE AddRef(void) override { return ++m_nRefCount; } - ULONG Release(void) override { + ULONG STDMETHODCALLTYPE Release(void) override { size_t ret = --m_nRefCount; if (ret == 0) delete this; @@ -67,7 +67,7 @@ public: : m_lambda(lambda) { } // baseT method - HRESULT Invoke(argTs ...args) override { + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { return m_lambda(args...); } private: @@ -81,7 +81,7 @@ public: : m_ctx(ctx), m_mthd(mthd) { } // baseT method - HRESULT Invoke(argTs ...args) override { + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { return (m_ctx->*m_mthd)(args...); } private: From a8b726359b288b9eb14151785e4b541198c640a1 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Wed, 27 Jan 2021 22:41:40 +0100 Subject: [PATCH 15/23] Format wxWebViewEdge Callback code --- src/msw/webview_edge.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index c4cbe16427..74baf46e1c 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -36,7 +36,7 @@ public: CInvokable() : m_nRefCount(0) {} virtual ~CInvokable() {} // IUnknown methods - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void **ppvObj) override + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void** ppvObj) override { /** * WebView2 Runtime apparently doesn't use this method, so it doesn't @@ -47,10 +47,12 @@ public: *ppvObj = NULL; return E_NOINTERFACE; } - ULONG STDMETHODCALLTYPE AddRef(void) override { + ULONG STDMETHODCALLTYPE AddRef() override + { return ++m_nRefCount; } - ULONG STDMETHODCALLTYPE Release(void) override { + ULONG STDMETHODCALLTYPE Release() override + { size_t ret = --m_nRefCount; if (ret == 0) delete this; @@ -59,51 +61,58 @@ public: private: std::atomic m_nRefCount; }; + template class CInvokableLambda : public CInvokable { public: CInvokableLambda(std::function lambda) - : m_lambda(lambda) { - } + : m_lambda(lambda) + {} // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { return m_lambda(args...); } private: std::function m_lambda; }; + template class CInvokableMethod : public CInvokable { public: - CInvokableMethod(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) - : m_ctx(ctx), m_mthd(mthd) { - } + CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) + : m_ctx(ctx), m_mthd(mthd) + {} // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override { + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { return (m_ctx->*m_mthd)(args...); } private: - contextT *m_ctx; - HRESULT (contextT::*m_mthd)(argTs...); + contextT* m_ctx; + HRESULT(contextT::* m_mthd)(argTs...); }; + // the function templates to generate concrete classes from above class templates template < typename baseT, typename lambdaT, // base type & lambda type typename LT, typename ...argTs // for capturing argument types of lambda > -wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT (LT::*)(argTs...) const) +wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT(LT::*)(argTs...) const) { return wxCOMPtr(new CInvokableLambda(lambda)); } + template wxCOMPtr Callback(lambdaT&& lambda) { return Callback_impl(std::move(lambda), &lambdaT::operator()); } + template -wxCOMPtr Callback(contextT *ctx, HRESULT (contextT::*mthd)(argTs...)) +wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) { return wxCOMPtr(new CInvokableMethod(ctx, mthd)); } From 156eda92d7bb9c6bd002c1aa739778e7e77f3158 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 21 Feb 2021 21:07:13 +0100 Subject: [PATCH 16/23] Use WRL when building with MSVC --- src/msw/webview_edge.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 74baf46e1c..0a73de5d08 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -27,6 +27,11 @@ #include "wx/msw/private/webview_edge.h" #include + +#ifdef __VISUALC__ +#include +using namespace Microsoft::WRL; +#else #include template @@ -116,6 +121,7 @@ wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) { return wxCOMPtr(new CInvokableMethod(ctx, mthd)); } +#endif // !__VISUALC__ wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView); From 66d314c232df7298cf5c792804325943eec6501c Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 25 Feb 2021 21:41:51 +0100 Subject: [PATCH 17/23] Implement QueryInterface of wxWebViewEdge CInvokable --- src/msw/webview_edge.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 0a73de5d08..2aefc038b2 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -41,14 +41,15 @@ public: CInvokable() : m_nRefCount(0) {} virtual ~CInvokable() {} // IUnknown methods - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID WXUNUSED(riid), void** ppvObj) override + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override { - /** - * WebView2 Runtime apparently doesn't use this method, so it doesn't - * matter how we implement this. On the other hand, this method must be - * implemented to make this invokable type a concrete class instead of a - * abstract one. - */ + if (riid == __uuidof(baseT) || riid == IID_IUnknown) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + *ppvObj = NULL; return E_NOINTERFACE; } From b43803703dae91408b58793b9e84470e65388e2f Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Thu, 25 Feb 2021 22:01:47 +0100 Subject: [PATCH 18/23] Move Callback implementation to separate header file --- include/wx/msw/wrl/event.h | 104 +++++++++++++++++++++++++++++++++++++ src/msw/webview_edge.cpp | 93 +-------------------------------- 2 files changed, 105 insertions(+), 92 deletions(-) create mode 100644 include/wx/msw/wrl/event.h diff --git a/include/wx/msw/wrl/event.h b/include/wx/msw/wrl/event.h new file mode 100644 index 0000000000..71a2d86770 --- /dev/null +++ b/include/wx/msw/wrl/event.h @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/wrl/event.h +// Purpose: WRL event callback implementation +// Author: nns52k +// Created: 2021-02-25 +// Copyright: (c) 2021 wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_PRIVATE_WRL_H_ +#define _WX_MSW_PRIVATE_WRL_H_ + +#include + +template +class CInvokable : public baseT +{ +public: + CInvokable() : m_nRefCount(0) {} + virtual ~CInvokable() {} + // IUnknown methods + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override + { + if (riid == __uuidof(baseT) || riid == IID_IUnknown) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + *ppvObj = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() override + { + return ++m_nRefCount; + } + ULONG STDMETHODCALLTYPE Release() override + { + size_t ret = --m_nRefCount; + if (ret == 0) + delete this; + return ret; + } +private: + std::atomic m_nRefCount; +}; + +template +class CInvokableLambda : public CInvokable +{ +public: + CInvokableLambda(std::function lambda) + : m_lambda(lambda) + {} + // baseT method + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { + return m_lambda(args...); + } +private: + std::function m_lambda; +}; + +template +class CInvokableMethod : public CInvokable +{ +public: + CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) + : m_ctx(ctx), m_mthd(mthd) + {} + // baseT method + HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override + { + return (m_ctx->*m_mthd)(args...); + } +private: + contextT* m_ctx; + HRESULT(contextT::* m_mthd)(argTs...); +}; + +// the function templates to generate concrete classes from above class templates +template < + typename baseT, typename lambdaT, // base type & lambda type + typename LT, typename ...argTs // for capturing argument types of lambda +> +wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT(LT::*)(argTs...) const) +{ + return wxCOMPtr(new CInvokableLambda(lambda)); +} + +template +wxCOMPtr Callback(lambdaT&& lambda) +{ + return Callback_impl(std::move(lambda), &lambdaT::operator()); +} + +template +wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) +{ + return wxCOMPtr(new CInvokableMethod(ctx, mthd)); +} + +#endif // _WX_MSW_PRIVATE_WRL_H_ diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 2aefc038b2..7069536d72 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -26,102 +26,11 @@ #include "wx/msw/private/cotaskmemptr.h" #include "wx/msw/private/webview_edge.h" -#include - #ifdef __VISUALC__ #include using namespace Microsoft::WRL; #else -#include - -template -class CInvokable : public baseT -{ -public: - CInvokable() : m_nRefCount(0) {} - virtual ~CInvokable() {} - // IUnknown methods - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override - { - if (riid == __uuidof(baseT) || riid == IID_IUnknown) - { - *ppvObj = this; - AddRef(); - return S_OK; - } - - *ppvObj = NULL; - return E_NOINTERFACE; - } - ULONG STDMETHODCALLTYPE AddRef() override - { - return ++m_nRefCount; - } - ULONG STDMETHODCALLTYPE Release() override - { - size_t ret = --m_nRefCount; - if (ret == 0) - delete this; - return ret; - } -private: - std::atomic m_nRefCount; -}; - -template -class CInvokableLambda : public CInvokable -{ -public: - CInvokableLambda(std::function lambda) - : m_lambda(lambda) - {} - // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override - { - return m_lambda(args...); - } -private: - std::function m_lambda; -}; - -template -class CInvokableMethod : public CInvokable -{ -public: - CInvokableMethod(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) - : m_ctx(ctx), m_mthd(mthd) - {} - // baseT method - HRESULT STDMETHODCALLTYPE Invoke(argTs ...args) override - { - return (m_ctx->*m_mthd)(args...); - } -private: - contextT* m_ctx; - HRESULT(contextT::* m_mthd)(argTs...); -}; - -// the function templates to generate concrete classes from above class templates -template < - typename baseT, typename lambdaT, // base type & lambda type - typename LT, typename ...argTs // for capturing argument types of lambda -> -wxCOMPtr Callback_impl(lambdaT&& lambda, HRESULT(LT::*)(argTs...) const) -{ - return wxCOMPtr(new CInvokableLambda(lambda)); -} - -template -wxCOMPtr Callback(lambdaT&& lambda) -{ - return Callback_impl(std::move(lambda), &lambdaT::operator()); -} - -template -wxCOMPtr Callback(contextT* ctx, HRESULT(contextT::* mthd)(argTs...)) -{ - return wxCOMPtr(new CInvokableMethod(ctx, mthd)); -} +#include #endif // !__VISUALC__ wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEdge, wxWebView); From 09bc566b6055dc86666c75500a393b3a3dc1ba47 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Fri, 26 Feb 2021 20:33:36 +0100 Subject: [PATCH 19/23] Support building wxWebViewEdge with GCC or Clang Add EventToken.h with EventRegistrationToken implementation, that can be used by the WebView2 header. --- Makefile.in | 21 ++++++++++++++------- build/bakefiles/multilib.bkl | 6 ++++++ build/cmake/lib/webview/CMakeLists.txt | 3 +++ build/msw/makefile.gcc | 13 +++++++------ build/msw/makefile.vc | 2 +- include/wx/msw/wrl/EventToken.h | 18 ++++++++++++++++++ 6 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 include/wx/msw/wrl/EventToken.h diff --git a/Makefile.in b/Makefile.in index b9c14d553a..482cf73d26 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1690,15 +1690,16 @@ WEBVIEWDLL_CXXFLAGS = $(__webviewdll_PCH_INC) $(__INC_TIFF_BUILD_p) \ $(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING -DWXUSINGDLL \ - -DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_p) $(PIC_FLAG) \ - $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS) + -DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_wrl_p) \ + $(__webview_additional_include_p) $(PIC_FLAG) $(WX_CXXFLAGS) $(CPPFLAGS) \ + $(CXXFLAGS) WEBVIEWDLL_OBJCXXFLAGS = $(__webviewdll_PCH_INC) $(__INC_TIFF_BUILD_p) \ $(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \ $(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING -DWXUSINGDLL \ - -DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_p) $(PIC_FLAG) \ - $(CPPFLAGS) $(OBJCXXFLAGS) + -DWXMAKINGDLL_WEBVIEW $(__webview_additional_include_wrl_p) \ + $(__webview_additional_include_p) $(PIC_FLAG) $(CPPFLAGS) $(OBJCXXFLAGS) WEBVIEWDLL_OBJECTS = \ $(__WEBVIEW_SRC_PLATFORM_OBJECTS_2) \ webviewdll_webview.o \ @@ -1711,13 +1712,15 @@ WEBVIEWLIB_CXXFLAGS = $(__webviewlib_PCH_INC) $(__INC_TIFF_BUILD_p) \ $(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING \ - $(__webview_additional_include_p) $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS) + $(__webview_additional_include_wrl_p) $(__webview_additional_include_p) \ + $(WX_CXXFLAGS) $(CPPFLAGS) $(CXXFLAGS) WEBVIEWLIB_OBJCXXFLAGS = $(__webviewlib_PCH_INC) $(__INC_TIFF_BUILD_p) \ $(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \ $(__INC_REGEX_p) $(__INC_EXPAT_p) $(WX_CPPFLAGS) -D__WX$(TOOLKIT)__ \ $(__WXUNIV_DEFINE_p) $(__DEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) \ $(__RTTI_DEFINE_p) $(__THREAD_DEFINE_p) -DWXBUILDING \ - $(__webview_additional_include_p) $(CPPFLAGS) $(OBJCXXFLAGS) + $(__webview_additional_include_wrl_p) $(__webview_additional_include_p) \ + $(CPPFLAGS) $(OBJCXXFLAGS) WEBVIEWLIB_OBJECTS = \ $(__WEBVIEW_SRC_PLATFORM_OBJECTS_3) \ webviewlib_webview.o \ @@ -12397,6 +12400,8 @@ COND_USE_SOVERSOLARIS_1___webviewdll___so_symlinks_uninst_cmd = rm -f \ @COND_TOOLKIT_GTK@ webviewdll_webview_webkit2.o @COND_TOOLKIT_MSW@__WEBVIEW_SRC_PLATFORM_OBJECTS_2 = \ @COND_TOOLKIT_MSW@ webviewdll_webview_ie.o webviewdll_webview_edge.o +@COND_TOOLKIT_MSW@__webview_additional_include_wrl_p_1 = \ +@COND_TOOLKIT_MSW@ --include-dir $(top_srcdir)/include/wx/msw/wrl @COND_TOOLKIT_MSW@__webview_additional_include_p_1 = \ @COND_TOOLKIT_MSW@ --include-dir \ @COND_TOOLKIT_MSW@ $(top_srcdir)/3rdparty/webview2/build/native/include @@ -13792,6 +13797,8 @@ COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS_1_4 = \ corelib_core_timer.o \ corelib_utilsexc_cf.o @COND_PLATFORM_MACOSX_1@__OSX_LOWLEVEL_SRC_OBJECTS_1_4 = $(COND_PLATFORM_MACOSX_1___OSX_LOWLEVEL_SRC_OBJECTS_1_4) +@COND_TOOLKIT_MSW@__webview_additional_include_wrl_p = \ +@COND_TOOLKIT_MSW@ -I$(top_srcdir)/include/wx/msw/wrl @COND_TOOLKIT_MSW@__webview_additional_include_p = \ @COND_TOOLKIT_MSW@ -I$(top_srcdir)/3rdparty/webview2/build/native/include @COND_MONOLITHIC_0_SHARED_1_USE_GUI_1_USE_HTML_1@__htmldll_library_link_DEP \ @@ -36060,7 +36067,7 @@ webviewdll_webviewfshandler.o: $(srcdir)/src/common/webviewfshandler.cpp $(WEBVI $(CXXC) -c -o $@ $(WEBVIEWDLL_CXXFLAGS) $(srcdir)/src/common/webviewfshandler.cpp webviewdll_version_rc.o: $(srcdir)/src/msw/version.rc $(WEBVIEWDLL_ODEP) - $(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW $(__webview_additional_include_p_1) + $(WINDRES) -i$< -o$@ $(__INC_TIFF_BUILD_p_54) $(__INC_TIFF_p_54) $(__INC_JPEG_p_54) $(__INC_PNG_p_53) $(__INC_ZLIB_p_67) $(__INC_REGEX_p_65) $(__INC_EXPAT_p_65) --define __WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) --define WXBUILDING --define WXDLLNAME=$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG) $(__RCDEFDIR_p) --include-dir $(top_srcdir)/include --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW $(__webview_additional_include_wrl_p_1) $(__webview_additional_include_p_1) webviewlib_webview_ie.o: $(srcdir)/src/msw/webview_ie.cpp $(WEBVIEWLIB_ODEP) $(CXXC) -c -o $@ $(WEBVIEWLIB_CXXFLAGS) $(srcdir)/src/msw/webview_ie.cpp diff --git a/build/bakefiles/multilib.bkl b/build/bakefiles/multilib.bkl index 2dbd123173..05eafd756a 100644 --- a/build/bakefiles/multilib.bkl +++ b/build/bakefiles/multilib.bkl @@ -180,6 +180,10 @@ $(TOP_SRCDIR)3rdparty/webview2/build/native/include + + $(TOP_SRCDIR)include/wx/msw/wrl + + WXUSINGDLL @@ -189,6 +193,7 @@ basedll $(EXTRALIBS_WEBVIEW) $(WEBVIEW_HDR) + $(webview_additional_include_wrl) $(webview_additional_include) @@ -196,6 +201,7 @@ cond="SHARED=='0' and USE_GUI=='1' and USE_WEBVIEW=='1' and MONOLITHIC=='0'"> $(WEBVIEW_SRC) $(WEBVIEW_HDR) + $(webview_additional_include_wrl) $(webview_additional_include) diff --git a/build/cmake/lib/webview/CMakeLists.txt b/build/cmake/lib/webview/CMakeLists.txt index 56ab76375d..4cbf0fd900 100644 --- a/build/cmake/lib/webview/CMakeLists.txt +++ b/build/cmake/lib/webview/CMakeLists.txt @@ -67,6 +67,9 @@ elseif(WXMSW) endif() wx_lib_include_directories(wxwebview PRIVATE "${WEBVIEW2_PACKAGE_DIR}/build/native/include") + if(NOT MSVC) + wx_lib_include_directories(wxwebview PRIVATE "${wxSOURCE_DIR}/include/wx/msw/wrl") + endif() if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(WEBVIEW2_ARCH x86) diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 42f5adc99c..574f068211 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1140,9 +1140,9 @@ WEBVIEWDLL_CXXFLAGS = -I..\..\src\tiff\libtiff -I..\..\src\jpeg \ $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -I$(SETUPHDIR) -I..\..\include \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING -DWXUSINGDLL \ - -DWXMAKINGDLL_WEBVIEW -I..\..\3rdparty\webview2\build\native\include \ - $(__RTTIFLAG) $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) \ - $(CXXFLAGS) + -DWXMAKINGDLL_WEBVIEW -I..\..\include\wx\msw\wrl \ + -I..\..\3rdparty\webview2\build\native\include $(__RTTIFLAG) \ + $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) WEBVIEWDLL_OBJECTS = \ $(OBJS)\webviewdll_dummy.o \ $(OBJS)\webviewdll_webview_ie.o \ @@ -1158,8 +1158,9 @@ WEBVIEWLIB_CXXFLAGS = -I..\..\src\tiff\libtiff -I..\..\src\jpeg \ $(__NDEBUG_DEFINE_p) $(__EXCEPTIONS_DEFINE_p) $(__RTTI_DEFINE_p) \ $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -I$(SETUPHDIR) -I..\..\include \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING \ - -I..\..\3rdparty\webview2\build\native\include $(__RTTIFLAG) \ - $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) + -I..\..\include\wx\msw\wrl -I..\..\3rdparty\webview2\build\native\include \ + $(__RTTIFLAG) $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) \ + $(CXXFLAGS) WEBVIEWLIB_OBJECTS = \ $(OBJS)\webviewlib_dummy.o \ $(OBJS)\webviewlib_webview_ie.o \ @@ -16404,7 +16405,7 @@ $(OBJS)\webviewdll_webviewfshandler.o: ../../src/common/webviewfshandler.cpp $(CXX) -c -o $@ $(WEBVIEWDLL_CXXFLAGS) $(CPPDEPS) $< $(OBJS)\webviewdll_version_rc.o: ../../src/msw/version.rc - $(WINDRES) -i$< -o$@ --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../src/regex --include-dir ../../src/expat/expat/lib --define __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) --include-dir $(SETUPHDIR) --include-dir ../../include $(__CAIRO_INCLUDEDIR_p) --define WXBUILDING --define WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG) --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW --include-dir ../../3rdparty/webview2/build/native/include + $(WINDRES) -i$< -o$@ --include-dir ../../src/tiff/libtiff --include-dir ../../src/jpeg --include-dir ../../src/png --include-dir ../../src/zlib --include-dir ../../src/regex --include-dir ../../src/expat/expat/lib --define __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) --include-dir $(SETUPHDIR) --include-dir ../../include $(__CAIRO_INCLUDEDIR_p) --define WXBUILDING --define WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG) --define WXUSINGDLL --define WXMAKINGDLL_WEBVIEW --include-dir ../../include/wx/msw/wrl --include-dir ../../3rdparty/webview2/build/native/include $(OBJS)\webviewlib_dummy.o: ../../src/common/dummy.cpp $(CXX) -c -o $@ $(WEBVIEWLIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 536ca5edfc..792479410b 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -16854,7 +16854,7 @@ $(OBJS)\webviewdll_webviewfshandler.obj: ..\..\src\common\webviewfshandler.cpp $(CXX) /c /nologo /TP /Fo$@ $(WEBVIEWDLL_CXXFLAGS) ..\..\src\common\webviewfshandler.cpp $(OBJS)\webviewdll_version.res: ..\..\src\msw\version.rc - rc /fo$@ /d WIN32 /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\src\regex /i ..\..\src\expat\expat\lib $(____DEBUGRUNTIME_6) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_72) $(__TARGET_CPU_COMPFLAG_p_72) /d __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) /i $(SETUPHDIR) /i ..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) /d WXBUILDING /d WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG) /d WXUSINGDLL /d WXMAKINGDLL_WEBVIEW /i ..\..\3rdparty\webview2\build\native\include ..\..\src\msw\version.rc + rc /fo$@ /d WIN32 /i ..\..\src\tiff\libtiff /i ..\..\src\jpeg /i ..\..\src\png /i ..\..\src\zlib /i ..\..\src\regex /i ..\..\src\expat\expat\lib $(____DEBUGRUNTIME_6) /d _CRT_SECURE_NO_DEPRECATE=1 /d _CRT_NON_CONFORMING_SWPRINTFS=1 /d _SCL_SECURE_NO_WARNINGS=1 $(__NO_VC_CRTDBG_p_72) $(__TARGET_CPU_COMPFLAG_p_72) /d __WXMSW__ $(__WXUNIV_DEFINE_p_67) $(__DEBUG_DEFINE_p_66) $(__NDEBUG_DEFINE_p_65) $(__EXCEPTIONS_DEFINE_p_65) $(__RTTI_DEFINE_p_65) $(__THREAD_DEFINE_p_65) $(__UNICODE_DEFINE_p_67) /i $(SETUPHDIR) /i ..\..\include $(____CAIRO_INCLUDEDIR_FILENAMES_4) /d WXBUILDING /d WXDLLNAME=wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_webview$(WXCOMPILER)$(VENDORTAG) /d WXUSINGDLL /d WXMAKINGDLL_WEBVIEW /i ..\..\3rdparty\webview2\build\native\include ..\..\src\msw\version.rc $(OBJS)\webviewlib_dummy.obj: ..\..\src\common\dummy.cpp $(CXX) /c /nologo /TP /Fo$@ $(WEBVIEWLIB_CXXFLAGS) /Ycwx/wxprec.h ..\..\src\common\dummy.cpp diff --git a/include/wx/msw/wrl/EventToken.h b/include/wx/msw/wrl/EventToken.h new file mode 100644 index 0000000000..3b79b3a26d --- /dev/null +++ b/include/wx/msw/wrl/EventToken.h @@ -0,0 +1,18 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/wrl/EventToken.h +// Purpose: WRL EventRegistrationToken implementation +// Author: Maarten Bent +// Created: 2021-02-26 +// Copyright: (c) 2021 wxWidgets team +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __eventtoken_h__ +#define __eventtoken_h__ + +typedef struct EventRegistrationToken +{ + __int64 value; +} EventRegistrationToken; + +#endif // __eventtoken_h__ From fc3cfb67cf1dc03620640209364d8befaddf0465 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 27 Feb 2021 16:34:14 +0100 Subject: [PATCH 20/23] Add missing UUIDs for wxWebViewEdge --- include/wx/msw/private/webview_edge.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/wx/msw/private/webview_edge.h b/include/wx/msw/private/webview_edge.h index 146d87d34c..cf774f8c86 100644 --- a/include/wx/msw/private/webview_edge.h +++ b/include/wx/msw/private/webview_edge.h @@ -19,6 +19,23 @@ #error "WebView2 SDK version 0.9.430 or newer is required" #endif +#ifndef __VISUALC__ +__CRT_UUID_DECL(ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler, 0xb99369f3, 0x9b11, 0x47b5, 0xbc,0x6f, 0x8e,0x78,0x95,0xfc,0xea,0x17); +__CRT_UUID_DECL(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler, 0x6c4819f3, 0xc9b7, 0x4260, 0x81,0x27, 0xc9,0xf5,0xbd,0xe7,0xf6,0x8c); +__CRT_UUID_DECL(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, 0x4e8a3389, 0xc9d8, 0x4bd2, 0xb6,0xb5, 0x12,0x4f,0xee,0x6c,0xc1,0x4d); +__CRT_UUID_DECL(ICoreWebView2ContainsFullScreenElementChangedEventHandler, 0xe45d98b1, 0xafef, 0x45be, 0x8b,0xaf, 0x6c,0x77,0x28,0x86,0x7f,0x73); +__CRT_UUID_DECL(ICoreWebView2ContentLoadingEventHandler, 0x364471e7, 0xf2be, 0x4910, 0xbd,0xba, 0xd7,0x20,0x77,0xd5,0x1c,0x4b); +__CRT_UUID_DECL(ICoreWebView2DocumentTitleChangedEventHandler, 0xf5f2b923, 0x953e, 0x4042, 0x9f,0x95, 0xf3,0xa1,0x18,0xe1,0xaf,0xd4); +__CRT_UUID_DECL(ICoreWebView2Environment, 0xb96d755e, 0x0319, 0x4e92, 0xa2,0x96, 0x23,0x43,0x6f,0x46,0xa1,0xfc); +__CRT_UUID_DECL(ICoreWebView2EnvironmentOptions, 0x2fde08a8, 0x1e9a, 0x4766, 0x8c,0x05, 0x95,0xa9,0xce,0xb9,0xd1,0xc5); +__CRT_UUID_DECL(ICoreWebView2ExecuteScriptCompletedHandler, 0x49511172, 0xcc67, 0x4bca, 0x99,0x23, 0x13,0x71,0x12,0xf4,0xc4,0xcc); +__CRT_UUID_DECL(ICoreWebView2NavigationCompletedEventHandler, 0xd33a35bf, 0x1c49, 0x4f98, 0x93,0xab, 0x00,0x6e,0x05,0x33,0xfe,0x1c); +__CRT_UUID_DECL(ICoreWebView2NavigationStartingEventHandler, 0x9adbe429, 0xf36d, 0x432b, 0x9d,0xdc, 0xf8,0x88,0x1f,0xbd,0x76,0xe3); +__CRT_UUID_DECL(ICoreWebView2NewWindowRequestedEventHandler, 0xd4c185fe, 0xc81c, 0x4989, 0x97,0xaf, 0x2d,0x3f,0xa7,0xab,0x56,0x51); +__CRT_UUID_DECL(ICoreWebView2SourceChangedEventHandler, 0x3c067f9f, 0x5388, 0x4772, 0x8b,0x48, 0x79,0xf7,0xef,0x1a,0xb3,0x7c); +__CRT_UUID_DECL(ICoreWebView2WebMessageReceivedEventHandler, 0x57213f19, 0x00e6, 0x49fa, 0x8e,0x07, 0x89,0x8e,0xa0,0x1e,0xcb,0xd2); +#endif + class wxWebViewEdgeImpl { public: From 272c9032347b1c1baec6f6d96d419c2d5055eaf3 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 28 Feb 2021 15:10:38 +0100 Subject: [PATCH 21/23] Silence unknown pragmas warning in the WebView2 header Using wxGCC_WARNING_SUPPRESS(unknown-pragmas) around the webview2 header does not work, so suppress it for the entire webview project. --- build/bakefiles/multilib.bkl | 6 ++++++ build/cmake/lib/webview/CMakeLists.txt | 1 + build/msw/makefile.gcc | 7 ++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build/bakefiles/multilib.bkl b/build/bakefiles/multilib.bkl index 05eafd756a..90ca606d72 100644 --- a/build/bakefiles/multilib.bkl +++ b/build/bakefiles/multilib.bkl @@ -184,6 +184,10 @@ $(TOP_SRCDIR)include/wx/msw/wrl + + -Wno-unknown-pragmas + + WXUSINGDLL @@ -195,6 +199,7 @@ $(WEBVIEW_HDR) $(webview_additional_include_wrl) $(webview_additional_include) + $(webview_edge_pragma_warning) $(WEBVIEW_HDR) $(webview_additional_include_wrl) $(webview_additional_include) + $(webview_edge_pragma_warning) diff --git a/build/cmake/lib/webview/CMakeLists.txt b/build/cmake/lib/webview/CMakeLists.txt index 4cbf0fd900..e2ddeb44fb 100644 --- a/build/cmake/lib/webview/CMakeLists.txt +++ b/build/cmake/lib/webview/CMakeLists.txt @@ -69,6 +69,7 @@ elseif(WXMSW) wx_lib_include_directories(wxwebview PRIVATE "${WEBVIEW2_PACKAGE_DIR}/build/native/include") if(NOT MSVC) wx_lib_include_directories(wxwebview PRIVATE "${wxSOURCE_DIR}/include/wx/msw/wrl") + target_compile_options(wxwebview PRIVATE -Wno-unknown-pragmas) endif() if (CMAKE_SIZEOF_VOID_P EQUAL 4) diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 574f068211..6ff7d9af53 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1142,7 +1142,8 @@ WEBVIEWDLL_CXXFLAGS = -I..\..\src\tiff\libtiff -I..\..\src\jpeg \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING -DWXUSINGDLL \ -DWXMAKINGDLL_WEBVIEW -I..\..\include\wx\msw\wrl \ -I..\..\3rdparty\webview2\build\native\include $(__RTTIFLAG) \ - $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) $(CXXFLAGS) + $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy -Wno-unknown-pragmas $(CPPFLAGS) \ + $(CXXFLAGS) WEBVIEWDLL_OBJECTS = \ $(OBJS)\webviewdll_dummy.o \ $(OBJS)\webviewdll_webview_ie.o \ @@ -1159,8 +1160,8 @@ WEBVIEWLIB_CXXFLAGS = -I..\..\src\tiff\libtiff -I..\..\src\jpeg \ $(__THREAD_DEFINE_p) $(__UNICODE_DEFINE_p) -I$(SETUPHDIR) -I..\..\include \ $(____CAIRO_INCLUDEDIR_FILENAMES) -W -Wall -DWXBUILDING \ -I..\..\include\wx\msw\wrl -I..\..\3rdparty\webview2\build\native\include \ - $(__RTTIFLAG) $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy $(CPPFLAGS) \ - $(CXXFLAGS) + $(__RTTIFLAG) $(__EXCEPTIONSFLAG) -Wno-ctor-dtor-privacy \ + -Wno-unknown-pragmas $(CPPFLAGS) $(CXXFLAGS) WEBVIEWLIB_OBJECTS = \ $(OBJS)\webviewlib_dummy.o \ $(OBJS)\webviewlib_webview_ie.o \ From 753253280005dde65a625493234193088941fa27 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 28 Feb 2021 20:06:03 +0100 Subject: [PATCH 22/23] Mention GCC/Clang support in wxWebViewEdge documentation And add a comment explaining the name of the EventRegistrationToken include guard. --- include/wx/msw/wrl/EventToken.h | 3 +++ interface/wx/webview.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/wx/msw/wrl/EventToken.h b/include/wx/msw/wrl/EventToken.h index 3b79b3a26d..8d178baa5a 100644 --- a/include/wx/msw/wrl/EventToken.h +++ b/include/wx/msw/wrl/EventToken.h @@ -7,6 +7,9 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// +// Note: this include guard uses the same name as winrt/EventToken.h in the +// Windows SDK to prevent a struct type redefinition when both headers are +// included. #ifndef __eventtoken_h__ #define __eventtoken_h__ diff --git a/interface/wx/webview.h b/interface/wx/webview.h index 18581d2c9a..1df97b3d1a 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -320,7 +320,7 @@ public: virtual filesystems, custom urls. This backend is not enabled by default, to build it follow these steps: - - Visual Studio 2015, or newer, is required + - Visual Studio 2015 or newer, or GCC/Clang with c++11 is required - With CMake just enable @c wxUSE_WEBVIEW_EDGE - When not using CMake: - Download the WebView2 SDK From 401d547b2a8e1356dea0ba7cc49c90253c8fb159 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sun, 28 Feb 2021 15:45:51 +0100 Subject: [PATCH 23/23] Fix -Wdeprecated-copy warning when using Scintilla Window Don't use the copy constructor, use a constructor accepting the windowID. Closes https://github.com/wxWidgets/wxWidgets/pull/2259 --- src/stc/ScintillaWX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index ef06279ebd..44ee6a962c 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -616,7 +616,7 @@ bool ScintillaWX::CanPaste() { void ScintillaWX::CreateCallTipWindow(PRectangle) { if (! ct.wCallTip.Created() ) { ct.wCallTip = new wxSTCCallTip(stc, &ct, this); - ct.wDraw = ct.wCallTip; + ct.wDraw = ct.wCallTip.GetID(); } }