#18851: wxWebViewBackendEdge, always invisible is parent is hidden at construction

86 views
Skip to first unread message

wxTrac

unread,
Jul 24, 2020, 12:32:54 PM7/24/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible is parent is hidden at construction
---------------------+-------------------------
Reporter: ericj | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Keywords: | Blocked By:
Blocking: | Patch: 1
---------------------+-------------------------
With wxWebViewBackendEdge, the wxWebView will always stay invisible if its
parent is hidden when the wxWebView is constructed.

See patch to "webview" sample for demonstration. In it an additional panel
is introduced as parent for the wxWebView. A new menu entry is added to
toggle visibility of the panel.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851>

wxTrac

unread,
Jul 24, 2020, 12:33:06 PM7/24/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible is parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by ericj):

* Attachment "webview_edge_hidden_parent.patch" added.

wxTrac

unread,
Jul 24, 2020, 12:37:28 PM7/24/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by ericj):

* cc: ericj (added)


--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:1>

wxTrac

unread,
Jul 24, 2020, 12:42:59 PM7/24/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: new
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by ericj):

* cc: ericj (removed)


Comment:

Addition: Is it not enough to just Show() the parent before
wxWebView::New() and then calling Hide() again afterwards. Probably
because of the asynchronous nature of the webview2 construction.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:2>

wxTrac

unread,
Dec 8, 2020, 1:09:16 PM12/8/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by robind):

* status: new => confirmed


Comment:

We've seen this in wxPython as well.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:3>

wxTrac

unread,
Dec 8, 2020, 2:13:59 PM12/8/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by pb101):

* cc: pbfordev@… (added)


Comment:

I believe it was fixed in
https://github.com/wxWidgets/wxWidgets/commit/52138fc1f15070f3cb4895fe4aa447589e88c768

See the second commit in the PR.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:4>

wxTrac

unread,
Dec 8, 2020, 2:20:47 PM12/8/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by ericj):

* cc: ericj (added)


Comment:

Based on the description i thought this should have fixed the bug. But
based on a quick test it didn't.

I won't have time for a proper test before thursday, i'll report back
then.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:5>

wxTrac

unread,
Dec 9, 2020, 12:04:21 PM12/9/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by pb101):

* cc: pbfordev@… (removed)


Comment:

I have looked into this and it seems that for some reason,
`wxWebViewEdge::OnShow()` is not called as expected. At first I thought
that show event (`WM_SHOWWINDOW`) is not sent to a window completely
covered by another window (`wxWebView` by the actual webview2 control) but
this is is not the case.

It seems that show event is not sent to deeper nested `wxWindow`s. For
example, in the code below, the hierarchy is ''MyFrame'' -> ''m_panel'' ->
''subPanel''. When toggling ''m_panel'' visibility, ''m_panel'' receives
the show event but its child, ''subPanel'', does not. ''subPanel''
receives the event only when the frame is closed.
{{{
#!cpp
#include <wx/wx.h>

class MyFrame: public wxFrame
{
public:
MyFrame() : wxFrame (nullptr, wxID_ANY, "Test")
{
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

wxButton* button = new wxButton(this, wxID_ANY, "Toggle Panel");
button->Bind(wxEVT_BUTTON,
[this](wxCommandEvent&){ m_panel->Show(!m_panel->IsShown());
Layout(); });
mainSizer->Add(button, wxSizerFlags().Expand().Border());

m_panel = new wxPanel(this);
#if 0
m_panel->Bind(wxEVT_SHOW,
[this](wxShowEvent&){ wxLogMessage("m_panel wxEVT_SHOW"); });
#endif
wxPanel* subPanel = new wxPanel(m_panel, wxID_ANY, wxPoint(25,
25), wxSize(200, 200));
subPanel->SetBackgroundColour(*wxRED);
subPanel->Bind(wxEVT_SHOW,
[this](wxShowEvent&){ wxLogMessage("subPanel wxEVT_SHOW"); });
mainSizer->Add(m_panel, wxSizerFlags(1).Expand().Border());

SetSizer(mainSizer);
}
private:
wxPanel* m_panel;
};

class MyApp : public wxApp
{
public:
bool OnInit() override
{
(new MyFrame())->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);
}}}



So, this simple change fixes the webview2 issue but it is obviously a
wrong thing to do.
{{{
#!diff
src/msw/webview_edge.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp
index 2dba6fffb1..7f37e50f90 100644
--- a/src/msw/webview_edge.cpp
+++ b/src/msw/webview_edge.cpp
@@ -357,7 +357,8 @@ ICoreWebView2Settings*
wxWebViewEdgeImpl::GetSettings()

wxWebViewEdge::~wxWebViewEdge()
{
- Unbind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this);
+ if ( GetParent() )
+ GetParent()->Unbind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this);
delete m_impl;
}

@@ -382,7 +383,7 @@ bool wxWebViewEdge::Create(wxWindow* parent,
if (!m_impl->Create())
return false;
Bind(wxEVT_SIZE, &wxWebViewEdge::OnSize, this);
- Bind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this);
+ GetParent()->Bind(wxEVT_SHOW, &wxWebViewEdge::OnShow, this);

LoadURL(url);
return true;
}}}

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:6>

wxTrac

unread,
Dec 14, 2020, 4:35:46 AM12/14/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by TcT):

* cc: github@… (added)


Comment:

Maybe the correct solution would be to bind the event to the top level
window?

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:7>

wxTrac

unread,
Dec 14, 2020, 6:41:07 AM12/14/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------

Comment (by vadz):

The documentation is not clear and I'm not even sure if a window is
supposed to receive `wxEVT_SHOW` when its parent or grandparent visibility
changes.

On one hand, it seems like it would be useful to always get, but OTOH
sending this event to all windows in a large window hierarchy might take a
non-trivial amount of time, so I'm not sure if it's a good idea.

Then there is also the issue of consistency between ports -- I have no
idea what do the other ones do here.

Finally, in this precise case, I don't really understand why do we need
`wxWebViewEdge::OnShow()` at all: isn't the window going to be hidden
anyhow if its parent is hidden?

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:8>

wxTrac

unread,
Dec 14, 2020, 7:32:02 AM12/14/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by TcT):

* cc: github@… (removed)


Comment:

Replying to [comment:8 vadz]:

> Finally, in this precise case, I don't really understand why do we need
`wxWebViewEdge::OnShow()` at all: isn't the window going to be hidden
anyhow if its parent is hidden?

The problem in this case is the edge API where the window never gets
correctly shown if created while it's not visible. I would assume it has
something do do with how it's composed (probably out of process). I would
also assume that edge might use the put_IsVisible() for some background
optimization.

Handling it in OnShow seems to work, but maybe handling various levels of
parent windows is required to get it to work, when placed on child
windows.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:9>

wxTrac

unread,
Dec 14, 2020, 8:19:04 AM12/14/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------

Comment (by MaartenB):

I think binding to the parent or top level window will not work, because
you can only bind once. If the user binds to the show event of that window
as well, the webview won't get it.

What about binding to the paint event of the webview, and the first time
it is received call `put_IsVisible(true)`. The disadvantage is you won't
know when to call `put_IsVisible(false)`.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:10>

wxTrac

unread,
Dec 14, 2020, 2:02:57 PM12/14/20
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+------------------------
Reporter: ericj | Owner:
Type: defect | Status: confirmed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+------------------------
Changes (by pb101):

* cc: pbfordev@… (added)


Comment:

Sorry, I am probably missing something because why not just always turn
the visibility on in `wxWebViewEdgeImpl::OnWebViewCreated()`, e.g. like
here:
https://github.com/PBfordev/wxWidgets/commit/2a5b8d0298ec93fa5843826712a3dd3490a3f442

Because we normally want to have every control visible upon creating, just
as any native child window is created with `WS_VISIBLE`, right? Is there
still some issue, async or something, even in `OnWebViewCreated()`?

BTW, Microsoft recommends turning webview2 visibility off/on when
minimizing/restoring its top-level parent, for performance reasons. This
could be possible by binding `wxEVT_ICONIZE` using
`wxGetTopLevelParent()`.

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:11>

wxTrac

unread,
Feb 8, 2021, 7:51:43 AM2/8/21
to wx-...@googlegroups.com
#18851: wxWebViewBackendEdge, always invisible if parent is hidden at construction
----------------------+---------------------------------------
Reporter: ericj | Owner: Tobias Taschner <TcT2k@…>
Type: defect | Status: closed
Priority: normal | Milestone:
Component: WebView | Version: dev-latest
Resolution: fixed | Keywords:
Blocked By: | Blocking:
Patch: 1 |
----------------------+---------------------------------------
Changes (by Tobias Taschner <TcT2k@…>):

* owner: => Tobias Taschner <TcT2k@…>
* status: confirmed => closed
* resolution: => fixed


Comment:

In [changeset:"623e6a4fc3312e73c339fef9cf971c777c383ead/git-wxWidgets"
623e6a4fc/git-wxWidgets]:
{{{
#!CommitTicketReference repository="git-wxWidgets"
revision="623e6a4fc3312e73c339fef9cf971c777c383ead"
Make wxWebViewEdge visible after creating

Fixes: #18851
}}}

--
Ticket URL: <https://trac.wxwidgets.org/ticket/18851#comment:12>
Reply all
Reply to author
Forward
0 new messages