-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WaylandBackend: Re-map toplevel upon becoming visible #1611
base: master
Are you sure you want to change the base?
Conversation
607b40b
to
f45eabe
Compare
I was able to hit |
When becoming invisible, a NULL buffer is attached to the toplevel's surface which unmaps it. The compositor resets their state and the surface may also be considered unconfigured. Upon becoming visible, the surface must be re-mapped using the same process during initialization (commit without a buffer and wait for configure) before we begin attaching an actual buffer. The default properties should also be recovered. Fixes: ValveSoftware#1456
f45eabe
to
965ad83
Compare
This comment was marked as resolved.
This comment was marked as resolved.
I don't use the gamescope reaper or mangoapp (I start gamescope separately from my application process), so it's possible that I broke something there. Though, when I run |
This comment was marked as resolved.
This comment was marked as resolved.
rebased on current-ish master
I have different issues and crashes since the virtual connector refactor (to the point where I cannot reproduce the crash this PR is fixing anymore), so I won't update this branch until those issues are fixed. I am quite busy so probably won't get to reporting those issues until several days from now however. |
Yeah, I think we're facing a different issue now, and the old issue may actually be fixed. Running something like I've been able to fix the segmentation fault with a patch ( diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp
index e924ac8..75c92bd 100644
--- a/src/Backends/WaylandBackend.cpp
+++ b/src/Backends/WaylandBackend.cpp
@@ -73,13 +73,13 @@ static inline uint32_t WaylandScaleToPhysical( uint32_t pValue, uint32_t pFactor
}
static inline uint32_t WaylandScaleToLogical( uint32_t pValue, uint32_t pFactor ) {
return div_roundup( pValue * WL_FRACTIONAL_SCALE_DENOMINATOR, pFactor );
}
static bool IsSurfacePlane( wl_surface *pSurface ) {
- return wl_proxy_get_tag( (wl_proxy *)pSurface ) == &GAMESCOPE_plane_tag;
+ return pSurface && (wl_proxy_get_tag( (wl_proxy *)pSurface ) == &GAMESCOPE_plane_tag);
}
#define WAYLAND_NULL() []<typename... Args> ( void *pData, Args... args ) { }
#define WAYLAND_USERDATA_TO_THIS(type, name) []<typename... Args> ( void *pData, Args... args ) { type *pThing = (type *)pData; pThing->name( std::forward<Args>(args)... ); }
// Libdecor puts its userdata ptr at the end... how fun! I shouldn't have spent so long writing this total atrocity to mankind. *In sway, this occurs if it is in an undisplayed workspace or if it is tiled and behind another window. |
Been looking a bit more into this. It looks like the issue is that the first window has an extra count on its |
I believe I've found the culprit, gamescope/src/Backends/WaylandBackend.cpp Lines 722 to 723 in ef1e8db
gamescope/src/Backends/WaylandBackend.cpp Lines 2116 to 2117 in ef1e8db
EDIT: diff --git a/src/Backends/WaylandBackend.cpp b/src/Backends/WaylandBackend.cpp
index e924ac8..7aed647 100644
--- a/src/Backends/WaylandBackend.cpp
+++ b/src/Backends/WaylandBackend.cpp
@@ -73,13 +73,13 @@ static inline uint32_t WaylandScaleToPhysical( uint32_t pValue, uint32_t pFactor
}
static inline uint32_t WaylandScaleToLogical( uint32_t pValue, uint32_t pFactor ) {
return div_roundup( pValue * WL_FRACTIONAL_SCALE_DENOMINATOR, pFactor );
}
static bool IsSurfacePlane( wl_surface *pSurface ) {
- return wl_proxy_get_tag( (wl_proxy *)pSurface ) == &GAMESCOPE_plane_tag;
+ return pSurface && (wl_proxy_get_tag( (wl_proxy *)pSurface ) == &GAMESCOPE_plane_tag);
}
#define WAYLAND_NULL() []<typename... Args> ( void *pData, Args... args ) { }
#define WAYLAND_USERDATA_TO_THIS(type, name) []<typename... Args> ( void *pData, Args... args ) { type *pThing = (type *)pData; pThing->name( std::forward<Args>(args)... ); }
// Libdecor puts its userdata ptr at the end... how fun! I shouldn't have spent so long writing this total atrocity to mankind.
@@ -717,13 +717,13 @@ namespace gamescope
zwp_pointer_constraints_v1 *m_pPointerConstraints = nullptr;
zwp_relative_pointer_manager_v1 *m_pRelativePointerManager = nullptr;
wp_fractional_scale_manager_v1 *m_pFractionalScaleManager = nullptr;
xdg_toplevel_icon_manager_v1 *m_pToplevelIconManager = nullptr;
// TODO: Restructure and remove the need for this.
- std::shared_ptr<CWaylandConnector> m_pFocusConnector;
+ std::weak_ptr<CWaylandConnector> m_pFocusConnector;
wl_data_device_manager *m_pDataDeviceManager = nullptr;
wl_data_device *m_pDataDevice = nullptr;
std::shared_ptr<std::string> m_pClipboard = nullptr;
zwp_primary_selection_device_manager_v1 *m_pPrimarySelectionDeviceManager = nullptr;
@@ -2038,13 +2038,13 @@ namespace gamescope
return std::span<const uint64_t>{ iter->second.begin(), iter->second.end() };
}
IBackendConnector *CWaylandBackend::GetCurrentConnector()
{
- return m_pFocusConnector.get();
+ return m_pFocusConnector.lock().get();
}
IBackendConnector *CWaylandBackend::GetConnector( GamescopeScreenType eScreenType )
{
if ( eScreenType == GAMESCOPE_SCREEN_TYPE_INTERNAL )
return GetCurrentConnector();
@@ -2110,13 +2110,13 @@ namespace gamescope
{
return true;
}
std::shared_ptr<IBackendConnector> CWaylandBackend::CreateVirtualConnector( uint64_t ulVirtualConnectorKey )
{
std::shared_ptr<CWaylandConnector> pConnector = std::make_shared<CWaylandConnector>( this, ulVirtualConnectorKey );
- if ( !m_pFocusConnector )
+ if ( m_pFocusConnector.expired() )
m_pFocusConnector = pConnector;
if ( !pConnector->Init() )
{
return nullptr;
} If no one has any better ideas on how to fix the problem, I'll submit this as a PR in a couple of days. At the very least, it's better than the current situation. |
For me this patch properly fixes the issue on latest master. |
When becoming invisible, a NULL buffer is attached to the toplevel's surface which unmaps it. The compositor resets their state and the surface may also be considered unconfigured. Upon becoming visible, the surface must be re-mapped using the same process during initialization (commit without a buffer and wait for configure) before we begin attaching an actual buffer. The default properties should also be recovered.
Fixes: #1456