diff --git a/profiler/src/BackendWayland.cpp b/profiler/src/BackendWayland.cpp index feea6379..c33382e4 100644 --- a/profiler/src/BackendWayland.cpp +++ b/profiler/src/BackendWayland.cpp @@ -194,6 +194,7 @@ struct Output { int32_t scale; wl_output* obj; + bool entered; }; static std::unordered_map> s_output; static int s_maxScale = 1; @@ -207,6 +208,16 @@ static uint64_t s_time; static wl_fixed_t s_wheelAxisX, s_wheelAxisY; static bool s_wheel; +static void RecomputeScale() +{ + int max = 1; + for( auto& out : s_output ) + { + if( out.second->entered && out.second->scale > max ) max = out.second->scale; + } + s_maxScale = max; +} + static void PointerEnter( void*, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surf, wl_fixed_t sx, wl_fixed_t sy ) { wl_pointer_set_cursor( pointer, serial, s_cursorSurf, s_cursorX, s_cursorY ); @@ -471,12 +482,7 @@ static void OutputMode( void*, struct wl_output* output, uint32_t flags, int32_t static void OutputDone( void*, struct wl_output* output ) { - int max = 1; - for( auto& out : s_output ) - { - if( out.second->scale > max ) max = out.second->scale; - } - s_maxScale = max; + RecomputeScale(); } static void OutputScale( void* data, struct wl_output* output, int32_t scale ) @@ -529,7 +535,7 @@ static void RegistryGlobal( void*, struct wl_registry* reg, uint32_t name, const else if( strcmp( interface, wl_output_interface.name ) == 0 ) { auto output = (wl_output*)wl_registry_bind( reg, name, &wl_output_interface, 2 ); - auto ptr = std::make_unique( Output { 1, output } ); + auto ptr = std::make_unique( Output { 1, output, false } ); wl_output_add_listener( output, &outputListener, ptr.get() ); s_output.emplace( name, std::move( ptr ) ); } @@ -545,6 +551,7 @@ static void RegistryGlobalRemove( void*, struct wl_registry* reg, uint32_t name if( it == s_output.end() ) return; wl_output_destroy( it->second->obj ); s_output.erase( it ); + RecomputeScale(); } constexpr struct wl_registry_listener registryListener = { @@ -603,6 +610,37 @@ constexpr struct xdg_toplevel_listener toplevelListener = { .close = XdgToplevelClose }; +static void SurfaceEnter( void*, struct wl_surface* surface, struct wl_output* output ) +{ + for ( auto& out : s_output ) + { + if ( out.second->obj == output ) + { + out.second->entered = true; + RecomputeScale(); + break; + } + } +} + +static void SurfaceLeave( void*, struct wl_surface* surface, struct wl_output* output ) +{ + for ( auto& out : s_output ) + { + if ( out.second->obj == output ) + { + out.second->entered = false; + RecomputeScale(); + break; + } + } +} + +constexpr struct wl_surface_listener surfaceListener = { + .enter = SurfaceEnter, + .leave = SurfaceLeave, +}; + static void SetupCursor() { auto env_xcursor_theme = getenv( "XCURSOR_THEME" ); @@ -645,6 +683,7 @@ Backend::Backend( const char* title, const std::function& redraw, RunQue if( !s_seat ) { fprintf( stderr, "No wayland seat!\n" ); exit( 1 ); } s_surf = wl_compositor_create_surface( s_comp ); + wl_surface_add_listener( s_surf, &surfaceListener, nullptr ); s_eglWin = wl_egl_window_create( s_surf, m_winPos.w, m_winPos.h ); s_xdgSurf = xdg_wm_base_get_xdg_surface( s_wm, s_surf ); xdg_surface_add_listener( s_xdgSurf, &xdgSurfaceListener, nullptr );