From 2a728080957053b54446d0cebca2417e27c27d14 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 3 Mar 2019 11:35:30 +0100 Subject: [PATCH] Fix #3926: QCursor in AFP Fix a crash that occurred on the following steps: 1. Add an AFP track. 2. Open it, and move the waveform display to overlap the track label button. 3. Close the AFP window and open it again by clicking the track label. 4. Move the mouse pointer. The problem occurs because the code makes the implicit assumption that AudioFileProcessorWaveView::enterEvent (and hence QApplication::setOverrideCursor) is called before AudioFileProcessorWaveView::mouseMoveEvent. This is not the case when the waveform display is on top of the track label. In this case the AFP windows is opened with the mouse being immediately positioned over the wave form display. There is no enter event and move events are issues directly. This then leads to a crash in AudioFileProcessorWaveView::mouseMoveEvent when trying to determine the value for is_size_cursor because the override cursor is still null but is dereferenced directly without checking. Only adding a check would not solve the problem because in that case the cursor would not change to the hand cursor when being moved inside the waveform display. The solution is to remove all calls to the global methods setOverrideCursor and restoreOverrideCursor and to only set the cursor locally. This fix is based on a patch by gi0e5b06 which is committed under 8a10c52 in his repository but for which he never created a pull request. --- .../audio_file_processor.cpp | 47 ++++++++++--------- .../audio_file_processor.h | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 3135548999f..6be59f3cd0c 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -795,6 +795,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _ m_graph.fill( Qt::transparent ); update(); + updateCursor(); } @@ -811,7 +812,7 @@ void AudioFileProcessorWaveView::isPlaying( f_cnt_t _current_frame ) void AudioFileProcessorWaveView::enterEvent( QEvent * _e ) { - QApplication::setOverrideCursor( Qt::OpenHandCursor ); + updateCursor(); } @@ -819,10 +820,7 @@ void AudioFileProcessorWaveView::enterEvent( QEvent * _e ) void AudioFileProcessorWaveView::leaveEvent( QEvent * _e ) { - while( QApplication::overrideCursor() ) - { - QApplication::restoreOverrideCursor(); - } + updateCursor(); } @@ -850,7 +848,7 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me ) else { m_draggingType = wave; - QApplication::setOverrideCursor( Qt::ClosedHandCursor ); + updateCursor(_me); } } @@ -862,7 +860,7 @@ void AudioFileProcessorWaveView::mouseReleaseEvent( QMouseEvent * _me ) m_isDragging = false; if( m_draggingType == wave ) { - QApplication::restoreOverrideCursor(); + updateCursor(_me); } } @@ -873,22 +871,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent( QMouseEvent * _me ) { if( ! m_isDragging ) { - const bool is_size_cursor = - QApplication::overrideCursor()->shape() == Qt::SizeHorCursor; - - if( isCloseTo( _me->x(), m_startFrameX ) || - isCloseTo( _me->x(), m_endFrameX ) || - isCloseTo( _me->x(), m_loopFrameX ) ) - { - if( ! is_size_cursor ) - { - QApplication::setOverrideCursor( Qt::SizeHorCursor ); - } - } - else if( is_size_cursor ) - { - QApplication::restoreOverrideCursor(); - } + updateCursor(_me); return; } @@ -1261,6 +1244,24 @@ void AudioFileProcessorWaveView::reverse() +void AudioFileProcessorWaveView::updateCursor( QMouseEvent * _me ) +{ + bool const waveIsDragged = m_isDragging && (m_draggingType == wave); + bool const pointerCloseToStartEndOrLoop = (_me != nullptr ) && + ( isCloseTo( _me->x(), m_startFrameX ) || + isCloseTo( _me->x(), m_endFrameX ) || + isCloseTo( _me->x(), m_loopFrameX ) ); + + if( !m_isDragging && pointerCloseToStartEndOrLoop) + setCursor(Qt::SizeHorCursor); + else if( waveIsDragged ) + setCursor(Qt::ClosedHandCursor); + else + setCursor(Qt::OpenHandCursor); +} + + + void AudioFileProcessorWaveView::knob::slideTo( double _v, bool _check_bound ) { diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 150807686e9..d17be147c0c 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -211,7 +211,6 @@ class AudioFileProcessorWaveView : public QWidget private: bool checkBound( double _v ) const; - } ; @@ -276,6 +275,7 @@ public slots: void updateGraph(); void reverse(); + void updateCursor( QMouseEvent * _me = nullptr ); static bool isCloseTo( int _a, int _b ) {