Skip to content

Commit

Permalink
WaylandBackend: Fix scale equation and unscale libdecor frame commit
Browse files Browse the repository at this point in the history
This fixes the issue where in a scaled wayland sessions the window
buffer is the correct size with window decorations that are too large.

It also fixes gamescope being having a couple of pixels smaller when
fullscreen.
  • Loading branch information
ColinKinloch authored and misyltoad committed Nov 24, 2024
1 parent 7dd1bcd commit 37a348b
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions src/Backends/WaylandBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include "drm_include.h"

#define WL_FRACTIONAL_SCALE_DENOMINATOR 120

extern int g_nPreferredOutputWidth;
extern int g_nPreferredOutputHeight;
extern bool g_bForceHDR10OutputDebug;
Expand All @@ -63,6 +65,13 @@ auto CallWithAllButLast(Func pFunc, Args&&... args)
return Forwarder(std::forward_as_tuple(args...), std::make_index_sequence<sizeof...(Args) - 1>());
}

static inline uint32_t WaylandScaleToPhysical( uint32_t pValue, uint32_t pFactor ) {
return pValue * pFactor / WL_FRACTIONAL_SCALE_DENOMINATOR;
}
static inline uint32_t WaylandScaleToLogical( uint32_t pValue, uint32_t pFactor ) {
return div_roundup( pValue * WL_FRACTIONAL_SCALE_DENOMINATOR, pFactor );
}

#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)... ); }

Expand Down Expand Up @@ -1016,14 +1025,15 @@ namespace gamescope
wl_fixed_from_double( oState->flSrcHeight ) );
wp_viewport_set_destination(
m_pViewport,
oState->nDstWidth * 120 / uScale,
oState->nDstHeight * 120 / uScale);
WaylandScaleToLogical( oState->nDstWidth, uScale ),
WaylandScaleToLogical( oState->nDstHeight, uScale ) );

if ( m_pSubsurface )
{
wl_subsurface_set_position(
m_pSubsurface,
oState->nDestX * 120 / uScale,
oState->nDestY * 120 / uScale );
WaylandScaleToLogical( oState->nDestX, uScale ),
WaylandScaleToLogical( oState->nDestY, uScale ) );
}
// The x/y here does nothing? Why? What is it for...
// Use the subsurface set_position thing instead.
Expand All @@ -1041,7 +1051,10 @@ namespace gamescope

void CWaylandPlane::CommitLibDecor( libdecor_configuration *pConfiguration )
{
libdecor_state *pState = libdecor_state_new( g_nOutputWidth, g_nOutputHeight );
int32_t uScale = GetScale();
libdecor_state *pState = libdecor_state_new(
WaylandScaleToLogical( g_nOutputWidth, uScale ),
WaylandScaleToLogical( g_nOutputHeight, uScale ) );
libdecor_frame_commit( m_pFrame, pState, pConfiguration );
libdecor_state_free( pState );
}
Expand Down Expand Up @@ -1148,11 +1161,11 @@ namespace gamescope
int nWidth, nHeight;
if ( !libdecor_configuration_get_content_size( pConfiguration, m_pFrame, &nWidth, &nHeight ) )
{
nWidth = g_nOutputWidth * 120 / uScale;
nHeight = g_nOutputHeight * 120 / uScale;
nWidth = WaylandScaleToLogical( g_nOutputWidth, uScale );
nHeight = WaylandScaleToLogical( g_nOutputHeight, uScale );
}
g_nOutputWidth = nWidth * uScale / 120;
g_nOutputHeight = nHeight * uScale / 120;
g_nOutputWidth = WaylandScaleToPhysical( nWidth, uScale );
g_nOutputHeight = WaylandScaleToPhysical( nHeight, uScale );

CommitLibDecor( pConfiguration );

Expand Down

0 comments on commit 37a348b

Please sign in to comment.