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
This commit is contained in:
Garux 2022-11-07 19:02:40 +03:00
parent f7a33dd4d3
commit 15ca706037
5 changed files with 78 additions and 63 deletions

View File

@ -59,8 +59,8 @@ public:
m_func( func ) m_func( func )
{ {
} }
void motion( const QMouseEvent *event ){ void motion( const QMouseEvent& event ){
m_mouseMoveEvent = *event; m_mouseMoveEvent = event;
} }
void invoke(){ void invoke(){
m_func( m_mouseMoveEvent ); m_func( m_mouseMoveEvent );

View File

@ -1131,14 +1131,14 @@ void camera_orbit_init( camera_t& cam, Vector2 xy ){
cam.m_orbit = true; cam.m_orbit = true;
} }
inline bool ORBIT_EVENT( const QMouseEvent *event ){ inline bool ORBIT_EVENT( const QMouseEvent& event ){
return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierAlt; return event.button() == Qt::MouseButton::RightButton && modifiers_for_state( event.modifiers() ) == c_modifierAlt;
} }
inline bool M2_EVENT( const QMouseEvent *event ){ inline bool M2_EVENT( const QMouseEvent& event ){
return event->button() == Qt::MouseButton::RightButton && modifiers_for_state( event->modifiers() ) == c_modifierNone; 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 m2 = M2_EVENT( event );
const bool m2alt = ORBIT_EVENT( event ); const bool m2alt = ORBIT_EVENT( event );
if ( m2 || m2alt ) { if ( m2 || m2alt ) {
@ -1148,7 +1148,7 @@ static void enable_freelook_button_press( const QMouseEvent *event, CamWnd& camw
} }
else{ else{
if( m2alt ) 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.EnableFreeMove();
camwnd.m_rightClickTimer.start(); camwnd.m_rightClickTimer.start();
camwnd.m_rightClickMove = 0; 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 m2 = M2_EVENT( event );
const bool m2alt = ORBIT_EVENT( event ); const bool m2alt = ORBIT_EVENT( event );
if ( m2 || m2alt ) { if ( m2 || m2alt ) {
@ -1167,14 +1167,14 @@ static void disable_freelook_button_press( const QMouseEvent *event, CamWnd& cam
} }
else{ else{
if( m2alt ) 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_rightClickTimer.start();
camwnd.m_rightClickMove = 0; 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 m2 = M2_EVENT( event );
const bool m2alt = ORBIT_EVENT( event ); const bool m2alt = ORBIT_EVENT( event );
if ( m2 || m2alt ) { 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 ) ) 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 ){ 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() ) ); 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 ){ 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 ){ inline WindowVector windowvector_for_widget_centre( const QWidget* widget ){
const QPoint center = widget->rect().center(); 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 ) ) 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 ){ 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() ) ); 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 ){ 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(); 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 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().y()
: event->angleDelta().x(); : event.angleDelta().x();
if ( angleDelta > 0 ) { if ( angleDelta > 0 ) {
if ( cam.movementflags & MOVE_FOCUS ) { if ( cam.movementflags & MOVE_FOCUS ) {
@ -1308,7 +1308,7 @@ static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){
} }
Camera_Freemove_updateAxes( cam ); 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 ) { else if ( angleDelta < 0 ) {
if ( cam.movementflags & MOVE_FOCUS ) { if ( cam.movementflags & MOVE_FOCUS ) {
@ -1322,7 +1322,7 @@ static void wheelmove_scroll( const QWheelEvent *event, CamWnd& camwnd ){
} }
Camera_Freemove_updateAxes( cam ); 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; CamWnd& m_camwnd;
FBO *m_fbo{}; FBO *m_fbo{};
qreal m_scale;
public: public:
CamGLWidget( CamWnd& camwnd ) : QOpenGLWidget(), m_camwnd( camwnd ) { CamGLWidget( CamWnd& camwnd ) : QOpenGLWidget(), m_camwnd( camwnd ) {
setMouseTracking( true ); setMouseTracking( true );
@ -1600,15 +1601,16 @@ protected:
} }
void resizeGL( int w, int h ) override void resizeGL( int w, int h ) override
{ {
delete m_fbo; m_scale = devicePixelRatioF();
m_fbo = new FBO( w, h, true, g_camwindow_globals_private.m_MSAA ); m_camwnd.getCamera().width = float_to_integer( w * m_scale );
m_camwnd.getCamera().height = float_to_integer( h * m_scale );
m_camwnd.getCamera().width = w;
m_camwnd.getCamera().height = h;
Camera_updateProjection( m_camwnd.getCamera() ); Camera_updateProjection( m_camwnd.getCamera() );
m_camwnd.m_window_observer->onSizeChanged( m_camwnd.getCamera().width, m_camwnd.getCamera().height ); m_camwnd.m_window_observer->onSizeChanged( m_camwnd.getCamera().width, m_camwnd.getCamera().height );
m_camwnd.m_drawRequired = true; 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 void paintGL() override
{ {
@ -1632,17 +1634,17 @@ protected:
void mousePressEvent( QMouseEvent *event ) override { void mousePressEvent( QMouseEvent *event ) override {
if( !m_camwnd.m_bFreeMove ){ if( !m_camwnd.m_bFreeMove ){
setFocus(); setFocus();
selection_button_press( event, m_camwnd.m_window_observer ); selection_button_press( scaledEvent( event ), m_camwnd.m_window_observer );
enable_freelook_button_press( event, m_camwnd ); enable_freelook_button_press( scaledEvent( event ), m_camwnd );
} }
else{ else{
selection_button_press_freemove( this, event, m_camwnd.m_window_observer ); selection_button_press_freemove( this, scaledEvent( event ), m_camwnd.m_window_observer );
disable_freelook_button_press( event, m_camwnd ); disable_freelook_button_press( scaledEvent( event ), m_camwnd );
} }
} }
void mouseMoveEvent( QMouseEvent *event ) override { void mouseMoveEvent( QMouseEvent *event ) override {
if( !m_camwnd.m_bFreeMove ){ 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 ); m_camwnd.getCamera().m_idleDraw.queueDraw( DeferredMotion2::InvokeCaller( m_camwnd.m_deferred_motion ), false );
} }
else{ else{
@ -1651,11 +1653,11 @@ protected:
} }
void mouseReleaseEvent( QMouseEvent *event ) override { void mouseReleaseEvent( QMouseEvent *event ) override {
if( !m_camwnd.m_bFreeMove ){ 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{ else{
selection_button_release_freemove( this, event, m_camwnd.m_window_observer ); selection_button_release_freemove( this, scaledEvent( event ), m_camwnd.m_window_observer );
disable_freelook_button_release( event, m_camwnd ); disable_freelook_button_release( scaledEvent( event ), m_camwnd );
} }
} }
void wheelEvent( QWheelEvent *event ) override { void wheelEvent( QWheelEvent *event ) override {
@ -1664,7 +1666,14 @@ protected:
m_camwnd.m_parent->activateWindow(); m_camwnd.m_parent->activateWindow();
m_camwnd.m_parent->raise(); 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 );
} }
}; };

View File

@ -950,6 +950,7 @@ class ModelBrowserGLWidget : public QOpenGLWidget
{ {
ModelBrowser& m_modBro; ModelBrowser& m_modBro;
FBO *m_fbo{}; FBO *m_fbo{};
qreal m_scale;
MousePresses m_mouse; MousePresses m_mouse;
public: public:
ModelBrowserGLWidget( ModelBrowser& modelBrowser ) : QOpenGLWidget(), m_modBro( modelBrowser ) ModelBrowserGLWidget( ModelBrowser& modelBrowser ) : QOpenGLWidget(), m_modBro( modelBrowser )
@ -967,13 +968,14 @@ protected:
} }
void resizeGL( int w, int h ) override void resizeGL( int w, int h ) override
{ {
delete m_fbo; m_scale = devicePixelRatioF();
m_fbo = new FBO( w, h, true, m_modBro.m_MSAA ); m_modBro.m_width = float_to_integer( w * m_scale );
m_modBro.m_height = float_to_integer( h * m_scale );
m_modBro.m_width = w;
m_modBro.m_height = h;
m_modBro.m_originInvalid = true; m_modBro.m_originInvalid = true;
m_modBro.forEachModelInstance( models_set_transforms() ); 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 void paintGL() override
{ {
@ -995,7 +997,7 @@ protected:
else if ( press == MousePresses::Left || press == MousePresses::Right ) { else if ( press == MousePresses::Left || press == MousePresses::Right ) {
m_modBro.tracking_MouseDown(); m_modBro.tracking_MouseDown();
if ( press == MousePresses::Left ) { if ( press == MousePresses::Left ) {
m_modBro.testSelect( event->x(), event->y() ); m_modBro.testSelect( event->x() * m_scale, event->y() * m_scale );
} }
} }
} }

View File

@ -1633,6 +1633,7 @@ void TextureBrowser_filterSetModeIcon( QAction *action ){
class TexWndGLWidget : public QOpenGLWidget class TexWndGLWidget : public QOpenGLWidget
{ {
TextureBrowser& m_texBro; TextureBrowser& m_texBro;
qreal m_scale;
MousePresses m_mouse; MousePresses m_mouse;
public: public:
TexWndGLWidget( TextureBrowser& textureBrowser ) : QOpenGLWidget(), m_texBro( textureBrowser ) TexWndGLWidget( TextureBrowser& textureBrowser ) : QOpenGLWidget(), m_texBro( textureBrowser )
@ -1651,8 +1652,9 @@ protected:
} }
void resizeGL( int w, int h ) override void resizeGL( int w, int h ) override
{ {
m_texBro.m_width = w; m_scale = devicePixelRatioF();
m_texBro.m_height = h; 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.heightChanged();
m_texBro.m_originInvalid = true; m_texBro.m_originInvalid = true;
} }
@ -1674,7 +1676,7 @@ protected:
} }
else if ( press == MousePresses::Left || press == MousePresses::Middle ) { else if ( press == MousePresses::Left || press == MousePresses::Middle ) {
if ( !event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) 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 ){ void mouseDoubleClick( MousePresses::Result press ){
@ -1701,7 +1703,7 @@ protected:
TextureBrowser_Tracking_MouseUp( m_texBro ); TextureBrowser_Tracking_MouseUp( m_texBro );
} }
else if ( release == MousePresses::Left && event->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ) ) { 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 { void wheelEvent( QWheelEvent *event ) override {

View File

@ -442,13 +442,14 @@ class XYGLWidget : public QOpenGLWidget
XYWnd& m_xywnd; XYWnd& m_xywnd;
DeferredMotion m_deferred_motion; DeferredMotion m_deferred_motion;
FBO *m_fbo{}; FBO *m_fbo{};
qreal m_scale;
public: public:
XYGLWidget( XYWnd& xywnd ) : QOpenGLWidget(), m_xywnd( xywnd ), XYGLWidget( XYWnd& xywnd ) : QOpenGLWidget(), m_xywnd( xywnd ),
m_deferred_motion( [this]( const QMouseEvent& event ){ 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; 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 ); setMouseTracking( true );
@ -466,21 +467,22 @@ protected:
} }
void resizeGL( int w, int h ) override void resizeGL( int w, int h ) override
{ {
delete m_fbo; m_scale = devicePixelRatioF();
m_fbo = new FBO( w, h, false, g_xywindow_globals_private.m_MSAA ); m_xywnd.m_nWidth = float_to_integer( w * m_scale );
m_xywnd.m_nHeight = float_to_integer( h * m_scale );
m_xywnd.m_nWidth = w;
m_xywnd.m_nHeight = h;
m_xywnd.updateProjection(); m_xywnd.updateProjection();
m_xywnd.m_window_observer->onSizeChanged( m_xywnd.Width(), m_xywnd.Height() ); m_xywnd.m_window_observer->onSizeChanged( m_xywnd.Width(), m_xywnd.Height() );
m_xywnd.m_drawRequired = true; 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 void paintGL() override
{ {
if( m_fbo->m_samples != g_xywindow_globals_private.m_MSAA ){ if( m_fbo->m_samples != g_xywindow_globals_private.m_MSAA ){
delete m_fbo; 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() ) { 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.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 { void mouseMoveEvent( QMouseEvent *event ) override {
m_deferred_motion.motion( event ); m_deferred_motion.motion( event );
} }
void mouseReleaseEvent( QMouseEvent *event ) override { 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.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 { void wheelEvent( QWheelEvent *event ) override {
setFocus(); setFocus();
@ -530,10 +532,10 @@ protected:
g_pParentWnd->SetActiveXY( &m_xywnd ); g_pParentWnd->SetActiveXY( &m_xywnd );
} }
if ( event->angleDelta().y() > 0 ) { 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 ) { else if ( event->angleDelta().y() < 0 ) {
m_xywnd.ZoomOutWithMouse( event->x(), event->y() ); m_xywnd.ZoomOutWithMouse( event->x() * m_scale, event->y() * m_scale );
} }
} }