From 15ca7060372cb782be3e1afd7f95cba8926d8ac2 Mon Sep 17 00:00:00 2001 From: Garux Date: Mon, 7 Nov 2022 19:02:40 +0300 Subject: [PATCH] support DPI scaling by viewports rendering and input in certain scenarios e.g. in mac, kde, wayland or after QT_SCALE_FACTOR=1.25 ./install/radiant --- libs/gtkutil/cursor.h | 4 +- radiant/camwindow.cpp | 85 +++++++++++++++++++++++------------------ radiant/modelwindow.cpp | 14 ++++--- radiant/texwindow.cpp | 10 +++-- radiant/xywindow.cpp | 28 +++++++------- 5 files changed, 78 insertions(+), 63 deletions(-) diff --git a/libs/gtkutil/cursor.h b/libs/gtkutil/cursor.h index d2bc6f03..f14a5426 100644 --- a/libs/gtkutil/cursor.h +++ b/libs/gtkutil/cursor.h @@ -59,8 +59,8 @@ public: m_func( func ) { } - void motion( const QMouseEvent *event ){ - m_mouseMoveEvent = *event; + void motion( const QMouseEvent& event ){ + m_mouseMoveEvent = event; } void invoke(){ m_func( m_mouseMoveEvent ); diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index 032c3a80..92e3ea46 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -1131,14 +1131,14 @@ void camera_orbit_init( camera_t& cam, Vector2 xy ){ cam.m_orbit = true; } -inline bool ORBIT_EVENT( const QMouseEvent *event ){ - return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierAlt; +inline bool ORBIT_EVENT( const QMouseEvent& event ){ + return event.button() == Qt::MouseButton::RightButton && modifiers_for_state( event.modifiers() ) == c_modifierAlt; } -inline bool M2_EVENT( const QMouseEvent *event ){ - return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierNone; +inline bool M2_EVENT( const QMouseEvent& event ){ + return event.button() == Qt::MouseButton::RightButton && modifiers_for_state( event.modifiers() ) == c_modifierNone; } -static void enable_freelook_button_press( const QMouseEvent *event, CamWnd& camwnd ){ +static void enable_freelook_button_press( const QMouseEvent& event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); if ( m2 || m2alt ) { @@ -1148,7 +1148,7 @@ static void enable_freelook_button_press( const QMouseEvent *event, CamWnd& camw } else{ if( m2alt ) - camera_orbit_init( camwnd.getCamera(), Vector2( event->x(), event->y() ) ); + camera_orbit_init( camwnd.getCamera(), Vector2( event.x(), event.y() ) ); camwnd.EnableFreeMove(); camwnd.m_rightClickTimer.start(); camwnd.m_rightClickMove = 0; @@ -1156,7 +1156,7 @@ static void enable_freelook_button_press( const QMouseEvent *event, CamWnd& camw } } -static void disable_freelook_button_press( const QMouseEvent *event, CamWnd& camwnd ){ +static void disable_freelook_button_press( const QMouseEvent& event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); if ( m2 || m2alt ) { @@ -1167,14 +1167,14 @@ static void disable_freelook_button_press( const QMouseEvent *event, CamWnd& cam } else{ if( m2alt ) - camera_orbit_init( camwnd.getCamera(), Vector2( event->x(), event->y() ) ); + camera_orbit_init( camwnd.getCamera(), Vector2( event.x(), event.y() ) ); camwnd.m_rightClickTimer.start(); camwnd.m_rightClickMove = 0; } } } -static void disable_freelook_button_release( const QMouseEvent *event, CamWnd& camwnd ){ +static void disable_freelook_button_release( const QMouseEvent& event, CamWnd& camwnd ){ const bool m2 = M2_EVENT( event ); const bool m2alt = ORBIT_EVENT( event ); if ( m2 || m2alt ) { @@ -1192,13 +1192,13 @@ void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){ } -static void selection_button_press( const QMouseEvent *event, WindowObserver* observer ){ +static void selection_button_press( const QMouseEvent& event, WindowObserver* observer ){ if( !ORBIT_EVENT( event ) ) - observer->onMouseDown( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); + observer->onMouseDown( WindowVector( event.x(), event.y() ), button_for_button( event.button() ), modifiers_for_state( event.modifiers() ) ); } -static void selection_button_release( const QMouseEvent *event, WindowObserver* observer ){ - observer->onMouseUp( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); +static void selection_button_release( const QMouseEvent& event, WindowObserver* observer ){ + observer->onMouseUp( WindowVector( event.x(), event.y() ), button_for_button( event.button() ), modifiers_for_state( event.modifiers() ) ); } void selection_motion( const QMouseEvent& event, WindowObserver* observer ){ @@ -1208,16 +1208,16 @@ void selection_motion( const QMouseEvent& event, WindowObserver* observer ){ inline WindowVector windowvector_for_widget_centre( const QWidget* widget ){ const QPoint center = widget->rect().center(); - return WindowVector( center.x(), center.y() ); + return WindowVector( center.x(), center.y() ) * widget->devicePixelRatioF(); } -static void selection_button_press_freemove( QWidget* widget, const QMouseEvent *event, WindowObserver* observer ){ +static void selection_button_press_freemove( QWidget* widget, const QMouseEvent& event, WindowObserver* observer ){ if( !ORBIT_EVENT( event ) ) - observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); + observer->onMouseDown( windowvector_for_widget_centre( widget ), button_for_button( event.button() ), modifiers_for_state( event.modifiers() ) ); } -static void selection_button_release_freemove( QWidget* widget, const QMouseEvent *event, WindowObserver* observer ){ - observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); +static void selection_button_release_freemove( QWidget* widget, const QMouseEvent& event, WindowObserver* observer ){ + observer->onMouseUp( windowvector_for_widget_centre( widget ), button_for_button( event.button() ), modifiers_for_state( event.modifiers() ) ); } void CamWnd::selection_motion_freemove( const MotionDeltaValues& delta ){ @@ -1289,12 +1289,12 @@ static void camera_zoom( CamWnd& camwnd, float x, float y, float step ){ } } -static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){ +static void wheelmove_scroll( const QWheelEvent& event, CamWnd& camwnd ){ camera_t& cam = camwnd.getCamera(); - const int angleDelta = ( std::abs( event->angleDelta().y() ) > std::abs( event->angleDelta().x() ) ) // normal y() goes to x() with ALT pressed - ? event->angleDelta().y() - : event->angleDelta().x(); + const int angleDelta = ( std::abs( event.angleDelta().y() ) > std::abs( event.angleDelta().x() ) ) // normal y() goes to x() with ALT pressed + ? event.angleDelta().y() + : event.angleDelta().x(); if ( angleDelta > 0 ) { if ( cam.movementflags & MOVE_FOCUS ) { @@ -1308,7 +1308,7 @@ static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){ } Camera_Freemove_updateAxes( cam ); - camera_zoom( camwnd, event->x(), event->y(), g_camwindow_globals_private.m_nScrollMoveSpeed ); + camera_zoom( camwnd, event.x(), event.y(), g_camwindow_globals_private.m_nScrollMoveSpeed ); } else if ( angleDelta < 0 ) { if ( cam.movementflags & MOVE_FOCUS ) { @@ -1322,7 +1322,7 @@ static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){ } Camera_Freemove_updateAxes( cam ); - camera_zoom( camwnd, event->x(), event->y(), -g_camwindow_globals_private.m_nScrollMoveSpeed ); + camera_zoom( camwnd, event.x(), event.y(), -g_camwindow_globals_private.m_nScrollMoveSpeed ); } } @@ -1583,6 +1583,7 @@ class CamGLWidget : public QOpenGLWidget { CamWnd& m_camwnd; FBO *m_fbo{}; + qreal m_scale; public: CamGLWidget( CamWnd& camwnd ) : QOpenGLWidget(), m_camwnd( camwnd ) { setMouseTracking( true ); @@ -1600,15 +1601,16 @@ protected: } void resizeGL( int w, int h ) override { - delete m_fbo; - m_fbo = new FBO( w, h, true, g_camwindow_globals_private.m_MSAA ); - - m_camwnd.getCamera().width = w; - m_camwnd.getCamera().height = h; + m_scale = devicePixelRatioF(); + m_camwnd.getCamera().width = float_to_integer( w * m_scale ); + m_camwnd.getCamera().height = float_to_integer( h * m_scale ); Camera_updateProjection( m_camwnd.getCamera() ); m_camwnd.m_window_observer->onSizeChanged( m_camwnd.getCamera().width, m_camwnd.getCamera().height ); m_camwnd.m_drawRequired = true; + + delete m_fbo; + m_fbo = new FBO( m_camwnd.getCamera().width, m_camwnd.getCamera().height, true, g_camwindow_globals_private.m_MSAA ); } void paintGL() override { @@ -1632,17 +1634,17 @@ protected: void mousePressEvent( QMouseEvent *event ) override { if( !m_camwnd.m_bFreeMove ){ setFocus(); - selection_button_press( event, m_camwnd.m_window_observer ); - enable_freelook_button_press( event, m_camwnd ); + selection_button_press( scaledEvent( event ), m_camwnd.m_window_observer ); + enable_freelook_button_press( scaledEvent( event ), m_camwnd ); } else{ - selection_button_press_freemove( this, event, m_camwnd.m_window_observer ); - disable_freelook_button_press( event, m_camwnd ); + selection_button_press_freemove( this, scaledEvent( event ), m_camwnd.m_window_observer ); + disable_freelook_button_press( scaledEvent( event ), m_camwnd ); } } void mouseMoveEvent( QMouseEvent *event ) override { if( !m_camwnd.m_bFreeMove ){ - m_camwnd.m_deferred_motion.motion( event ); + m_camwnd.m_deferred_motion.motion( scaledEvent( event ) ); m_camwnd.getCamera().m_idleDraw.queueDraw( DeferredMotion2::InvokeCaller( m_camwnd.m_deferred_motion ), false ); } else{ @@ -1651,11 +1653,11 @@ protected: } void mouseReleaseEvent( QMouseEvent *event ) override { if( !m_camwnd.m_bFreeMove ){ - selection_button_release( event, m_camwnd.m_window_observer ); + selection_button_release( scaledEvent( event ), m_camwnd.m_window_observer ); } else{ - selection_button_release_freemove( this, event, m_camwnd.m_window_observer ); - disable_freelook_button_release( event, m_camwnd ); + selection_button_release_freemove( this, scaledEvent( event ), m_camwnd.m_window_observer ); + disable_freelook_button_release( scaledEvent( event ), m_camwnd ); } } void wheelEvent( QWheelEvent *event ) override { @@ -1664,7 +1666,14 @@ protected: m_camwnd.m_parent->activateWindow(); m_camwnd.m_parent->raise(); } - wheelmove_scroll( event, m_camwnd ); + wheelmove_scroll( scaledEvent( event ), m_camwnd ); + } +private: + QMouseEvent scaledEvent( const QMouseEvent *event ) const { + return QMouseEvent( event->type(), event->localPos() * m_scale, event->windowPos() * m_scale, event->screenPos() * m_scale, event->button(), event->buttons(), event->modifiers() ); + } + QWheelEvent scaledEvent( const QWheelEvent *event ) const { + return QWheelEvent( event->posF() * m_scale, event->globalPosF() * m_scale, event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), event->phase(), false ); } }; diff --git a/radiant/modelwindow.cpp b/radiant/modelwindow.cpp index a6283466..9ed1be3d 100644 --- a/radiant/modelwindow.cpp +++ b/radiant/modelwindow.cpp @@ -950,6 +950,7 @@ class ModelBrowserGLWidget : public QOpenGLWidget { ModelBrowser& m_modBro; FBO *m_fbo{}; + qreal m_scale; MousePresses m_mouse; public: ModelBrowserGLWidget( ModelBrowser& modelBrowser ) : QOpenGLWidget(), m_modBro( modelBrowser ) @@ -967,13 +968,14 @@ protected: } void resizeGL( int w, int h ) override { - delete m_fbo; - m_fbo = new FBO( w, h, true, m_modBro.m_MSAA ); - - m_modBro.m_width = w; - m_modBro.m_height = h; + m_scale = devicePixelRatioF(); + m_modBro.m_width = float_to_integer( w * m_scale ); + m_modBro.m_height = float_to_integer( h * m_scale ); m_modBro.m_originInvalid = true; m_modBro.forEachModelInstance( models_set_transforms() ); + + delete m_fbo; + m_fbo = new FBO( m_modBro.m_width, m_modBro.m_height, true, m_modBro.m_MSAA ); } void paintGL() override { @@ -995,7 +997,7 @@ protected: else if ( press == MousePresses::Left || press == MousePresses::Right ) { m_modBro.tracking_MouseDown(); if ( press == MousePresses::Left ) { - m_modBro.testSelect( event->x(), event->y() ); + m_modBro.testSelect( event->x() * m_scale, event->y() * m_scale ); } } } diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index 8e7f38a9..9d08664d 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -1633,6 +1633,7 @@ void TextureBrowser_filterSetModeIcon( QAction *action ){ class TexWndGLWidget : public QOpenGLWidget { TextureBrowser& m_texBro; + qreal m_scale; MousePresses m_mouse; public: TexWndGLWidget( TextureBrowser& textureBrowser ) : QOpenGLWidget(), m_texBro( textureBrowser ) @@ -1651,8 +1652,9 @@ protected: } void resizeGL( int w, int h ) override { - m_texBro.m_width = w; - m_texBro.m_height = h; + m_scale = devicePixelRatioF(); + m_texBro.m_width = float_to_integer( w * m_scale ); + m_texBro.m_height = float_to_integer( h * m_scale ); m_texBro.heightChanged(); m_texBro.m_originInvalid = true; } @@ -1674,7 +1676,7 @@ protected: } else if ( press == MousePresses::Left || press == MousePresses::Middle ) { if ( !event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) - SelectTexture( m_texBro, event->x(), event->y(), press == MousePresses::Middle ); + SelectTexture( m_texBro, event->x() * m_scale, event->y() * m_scale, press == MousePresses::Middle ); } } void mouseDoubleClick( MousePresses::Result press ){ @@ -1701,7 +1703,7 @@ protected: TextureBrowser_Tracking_MouseUp( m_texBro ); } else if ( release == MousePresses::Left && event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) { - TextureBrowser_ViewShader( m_texBro, event->modifiers(), event->x(), event->y() ); + TextureBrowser_ViewShader( m_texBro, event->modifiers(), event->x() * m_scale, event->y() * m_scale ); } } void wheelEvent( QWheelEvent *event ) override { diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 12cb0e68..955ec562 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -442,13 +442,14 @@ class XYGLWidget : public QOpenGLWidget XYWnd& m_xywnd; DeferredMotion m_deferred_motion; FBO *m_fbo{}; + qreal m_scale; public: XYGLWidget( XYWnd& xywnd ) : QOpenGLWidget(), m_xywnd( xywnd ), m_deferred_motion( [this]( const QMouseEvent& event ){ - if ( m_xywnd.chaseMouseMotion( event.x(), event.y() ) ) { + if ( m_xywnd.chaseMouseMotion( event.x() * m_scale, event.y() * m_scale ) ) { return; } - m_xywnd.XY_MouseMoved( event.x(), event.y(), buttons_for_state( event ) ); + m_xywnd.XY_MouseMoved( event.x() * m_scale, event.y() * m_scale, buttons_for_state( event ) ); } ) { setMouseTracking( true ); @@ -466,21 +467,22 @@ protected: } void resizeGL( int w, int h ) override { - delete m_fbo; - m_fbo = new FBO( w, h, false, g_xywindow_globals_private.m_MSAA ); - - m_xywnd.m_nWidth = w; - m_xywnd.m_nHeight = h; + m_scale = devicePixelRatioF(); + m_xywnd.m_nWidth = float_to_integer( w * m_scale ); + m_xywnd.m_nHeight = float_to_integer( h * m_scale ); m_xywnd.updateProjection(); m_xywnd.m_window_observer->onSizeChanged( m_xywnd.Width(), m_xywnd.Height() ); m_xywnd.m_drawRequired = true; + + delete m_fbo; + m_fbo = new FBO( m_xywnd.Width(), m_xywnd.Height(), false, g_xywindow_globals_private.m_MSAA ); } void paintGL() override { if( m_fbo->m_samples != g_xywindow_globals_private.m_MSAA ){ delete m_fbo; - m_fbo = new FBO( m_xywnd.m_nWidth, m_xywnd.m_nHeight, false, g_xywindow_globals_private.m_MSAA ); + m_fbo = new FBO( m_xywnd.Width(), m_xywnd.Height(), false, g_xywindow_globals_private.m_MSAA ); } if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() && m_fbo->bind() ) { @@ -506,17 +508,17 @@ protected: m_xywnd.ButtonState_onMouseDown( buttons_for_event_button( event ) ); - m_xywnd.onMouseDown( WindowVector( event->x(), event->y() ), button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); + m_xywnd.onMouseDown( WindowVector( event->x(), event->y() ) * m_scale, button_for_button( event->button() ), modifiers_for_state( event->modifiers() ) ); } void mouseMoveEvent( QMouseEvent *event ) override { m_deferred_motion.motion( event ); } void mouseReleaseEvent( QMouseEvent *event ) override { - m_xywnd.XY_MouseUp( event->x(), event->y(), buttons_for_event_button( event ) ); + m_xywnd.XY_MouseUp( event->x() * m_scale, event->y() * m_scale, buttons_for_event_button( event ) ); m_xywnd.ButtonState_onMouseUp( buttons_for_event_button( event ) ); - m_xywnd.chaseMouseMotion( event->x(), event->y() ); /* stop chaseMouseMotion this way */ + m_xywnd.chaseMouseMotion( event->x() * m_scale, event->y() * m_scale ); /* stop chaseMouseMotion this way */ } void wheelEvent( QWheelEvent *event ) override { setFocus(); @@ -530,10 +532,10 @@ protected: g_pParentWnd->SetActiveXY( &m_xywnd ); } if ( event->angleDelta().y() > 0 ) { - m_xywnd.ZoomInWithMouse( event->x(), event->y() ); + m_xywnd.ZoomInWithMouse( event->x() * m_scale, event->y() * m_scale ); } else if ( event->angleDelta().y() < 0 ) { - m_xywnd.ZoomOutWithMouse( event->x(), event->y() ); + m_xywnd.ZoomOutWithMouse( event->x() * m_scale, event->y() * m_scale ); } }