From c6d60e982ece9c213ad400a8b030db7ee2d4cde3 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 28 Feb 2020 19:39:13 +0100 Subject: [PATCH 01/10] Audio/MidiJack: Fix invalid read: (1) of #5408 This fixes reading from jack MIDI events in case where there are no jack MIDI events. --- src/core/midi/MidiJack.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index 568b6dae1..664e1f16d 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -174,19 +174,22 @@ void MidiJack::JackMidiRead(jack_nframes_t nframes) jack_nframes_t event_index = 0; jack_nframes_t event_count = jack_midi_get_event_count(port_buf); - jack_midi_event_get(&in_event, port_buf, 0); - for(i=0; i Date: Wed, 15 Apr 2020 21:56:21 +0200 Subject: [PATCH 02/10] Audio/MidiJack: Fix invalid read: (2) of #5408 This patch * makes `m_stopped` atomic * initializes `m_stopped` correctly to `true` * moves the initialization of `m_stopped` to the point where jack ports are already connected --- include/AudioJack.h | 3 ++- src/core/audio/AudioJack.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/AudioJack.h b/include/AudioJack.h index 9bbb3bd48..9c412e202 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -34,6 +34,7 @@ #include "AudioWeakJack.h" #endif +#include #include #include #include @@ -106,7 +107,7 @@ private: jack_client_t * m_client; bool m_active; - bool m_stopped; + std::atomic m_stopped; MidiJack *m_midiClient; QVector m_outputPorts; diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index bca41356b..ba0daae94 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -56,6 +56,8 @@ AudioJack::AudioJack( bool & _success_ful, Mixer* _mixer ) : m_framesDoneInCurBuf( 0 ), m_framesToDoInCurBuf( 0 ) { + m_stopped = true; + _success_ful = initJackClient(); if( _success_ful ) { @@ -201,8 +203,6 @@ bool AudioJack::initJackClient() void AudioJack::startProcessing() { - m_stopped = false; - if( m_active || m_client == NULL ) { return; @@ -245,6 +245,7 @@ void AudioJack::startProcessing() } } + m_stopped = false; free( ports ); } From e3cae805807dd512fe9c7a55e81486b87e9cb6ed Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 18 Apr 2020 10:04:21 +0200 Subject: [PATCH 03/10] Audio/MidiJack: Fix invalid read: (3) of #5408 This atomically unsets the MidiJack reference in AudioJack right before MidiJack is destroyed. This avoids AudioJack using a destroyed MidiJack object. --- include/AudioJack.h | 3 ++- src/core/audio/AudioJack.cpp | 4 ++-- src/core/midi/MidiJack.cpp | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/AudioJack.h b/include/AudioJack.h index 9c412e202..2006906af 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -58,6 +58,7 @@ public: // the jack callback is handled here, we call the midi client so that it can read // it's midi data during the callback AudioJack * addMidiClient(MidiJack *midiClient); + void removeMidiClient(void) { m_midiClient = nullptr; } jack_client_t * jackClient() {return m_client;}; inline static QString name() @@ -109,7 +110,7 @@ private: bool m_active; std::atomic m_stopped; - MidiJack *m_midiClient; + std::atomic m_midiClient; QVector m_outputPorts; jack_default_audio_sample_t * * m_tempOutBufs; surroundSampleFrame * m_outBuf; diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index ba0daae94..1c1628a04 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -346,8 +346,8 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) // add to the following sound processing if( m_midiClient && _nframes > 0 ) { - m_midiClient->JackMidiRead(_nframes); - m_midiClient->JackMidiWrite(_nframes); + m_midiClient.load()->JackMidiRead(_nframes); + m_midiClient.load()->JackMidiWrite(_nframes); } for( int c = 0; c < channels(); ++c ) diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index 664e1f16d..f71ef4a4c 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -116,6 +116,9 @@ MidiJack::~MidiJack() { if(jackClient()) { + // remove ourselves first (atomically), so we will not get called again + m_jackAudio->removeMidiClient(); + if( jack_port_unregister( jackClient(), m_input_port) != 0){ printf("Failed to unregister jack midi input\n"); } From 737fcd3e55827f19fb7bda1813a80a9c0ff55920 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 18 Apr 2020 10:08:21 +0200 Subject: [PATCH 04/10] JackMidi: Remove confusing warning at shutdown Warning is: ``` jack_port_unregister called with an incorrect port 0 Failed to unregister jack midi output ``` --- src/core/midi/MidiJack.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index f71ef4a4c..bd1e65111 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -95,6 +95,8 @@ MidiJack::MidiJack() : /* jack midi out not implemented JackMidiWrite and sendByte needs to be functional before enabling this + If you enable this, also enable the + corresponding jack_port_unregister line below m_output_port = jack_port_register( jackClient(), "MIDI out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); @@ -123,9 +125,11 @@ MidiJack::~MidiJack() printf("Failed to unregister jack midi input\n"); } + /* Unused yet, see the corresponding jack_port_register call if( jack_port_unregister( jackClient(), m_output_port) != 0){ printf("Failed to unregister jack midi output\n"); } + */ if(m_jackClient) { From 29a5abc30b5d5efa30b7f6b73fe06d76ec851cca Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Mon, 18 May 2020 18:58:48 +0200 Subject: [PATCH 05/10] Fix Qt 5.15 build issues (#5498) Add missing QPainterPath includes --- plugins/Eq/EqSpectrumView.h | 1 + src/gui/AutomationPatternView.cpp | 1 + src/gui/LmmsStyle.cpp | 1 + src/gui/editors/AutomationEditor.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/plugins/Eq/EqSpectrumView.h b/plugins/Eq/EqSpectrumView.h index cd3f17758..84feeff13 100644 --- a/plugins/Eq/EqSpectrumView.h +++ b/plugins/Eq/EqSpectrumView.h @@ -24,6 +24,7 @@ #define EQSPECTRUMVIEW_H #include +#include #include #include "fft_helpers.h" diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 448c233cb..9889a6b46 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "AutomationEditor.h" diff --git a/src/gui/LmmsStyle.cpp b/src/gui/LmmsStyle.cpp index e57e29e47..4fe5cb503 100644 --- a/src/gui/LmmsStyle.cpp +++ b/src/gui/LmmsStyle.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 5e8ea8a0a..74f15d358 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include From 109cdf6cf3c3ee3c40d228cb694da2521ac5b689 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Thu, 21 May 2020 22:45:01 +0200 Subject: [PATCH 06/10] Fix #5483: sf2_player: No crash when file is no soundfont (#5487) --- plugins/sf2_player/sf2_player.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index f7a09f01e..99add3505 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -358,18 +358,24 @@ void sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName ) // Add to map, if doesn't exist. else { - m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, true ); + bool loaded = false; + if( fluid_is_soundfont( sf2Ascii ) ) + { + m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, true ); - if( fluid_synth_sfcount( m_synth ) > 0 ) - { - // Grab this sf from the top of the stack and add to list - m_font = new sf2Font( fluid_synth_get_sfont( m_synth, 0 ) ); - s_fonts.insert( relativePath, m_font ); + if( fluid_synth_sfcount( m_synth ) > 0 ) + { + // Grab this sf from the top of the stack and add to list + m_font = new sf2Font( fluid_synth_get_sfont( m_synth, 0 ) ); + s_fonts.insert( relativePath, m_font ); + loaded = true; + } } - else + + if(!loaded) { - collectErrorForUI( sf2Instrument::tr( "A soundfont %1 could not be loaded." ).arg( QFileInfo( _sf2File ).baseName() ) ); - // TODO: Why is the filename missing when the file does not exist? + collectErrorForUI( sf2Instrument::tr( "A soundfont %1 could not be loaded." ). + arg( QFileInfo( _sf2File ).baseName() ) ); } } From d5a2366fc8755e6600e3f44f3b7532173425ba14 Mon Sep 17 00:00:00 2001 From: thmueller64 <64359888+thmueller64@users.noreply.github.com> Date: Wed, 20 May 2020 21:37:03 +0200 Subject: [PATCH 07/10] Fix #5504: invalid warning --- src/core/Mixer.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 38ee5c46d..3ab180840 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -1203,8 +1203,18 @@ MidiClient * Mixer::tryMidiClients() printf( "midi apple didn't work: client_name=%s\n", client_name.toUtf8().constData()); #endif - printf( "Couldn't create MIDI-client, neither with ALSA nor with " - "OSS. Will use dummy-MIDI-client.\n" ); + if(client_name != MidiDummy::name()) + { + if (client_name.isEmpty()) + { + printf("Unknown MIDI-client. "); + } + else + { + printf("Couldn't create %s MIDI-client. ", client_name.toUtf8().constData()); + } + printf("Will use dummy-MIDI-client.\n"); + } m_midiClientName = MidiDummy::name(); From 3a985ff1fc825051679bf694892d77d2fdb3d16a Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Sun, 24 May 2020 13:20:05 +0200 Subject: [PATCH 08/10] Fix #4201: BB editor: adjust cursor position (#5489) This fixes an offset for cursors whose pointer position varies between different themes. --- data/themes/classic/style.css | 2 ++ data/themes/default/style.css | 2 ++ include/Track.h | 9 ++++++++- src/core/Track.cpp | 17 +++++++++++++++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 112d8f05c..50a0155c9 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -618,6 +618,8 @@ TrackContentObjectView { qproperty-textColor: rgb( 255, 255, 255 ); qproperty-textShadowColor: rgb( 0, 0, 0 ); qproperty-gradient: true; /* boolean property, set true to have a gradient */ + /* finger tip offset of cursor */ + qproperty-mouseHotspotHand: 3px 3px; } /* instrument pattern */ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index a9af1139f..3ba61f48c 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -653,6 +653,8 @@ TrackContentObjectView { qproperty-textColor: #fff; qproperty-textShadowColor: rgba(0,0,0,200); qproperty-gradient: false; /* boolean property, set true to have a gradient */ + /* finger tip offset of cursor */ + qproperty-mouseHotspotHand: 7px 2px; } /* instrument pattern */ diff --git a/include/Track.h b/include/Track.h index bc9f161a9..bd1a9f36d 100644 --- a/include/Track.h +++ b/include/Track.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -201,6 +202,9 @@ class TrackContentObjectView : public selectableObject, public ModelView Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor ) Q_PROPERTY( QColor BBPatternBackground READ BBPatternBackground WRITE setBBPatternBackground ) Q_PROPERTY( bool gradient READ gradient WRITE setGradient ) + // We have to use a QSize here because using QPoint isn't supported. + // width -> x, height -> y + Q_PROPERTY( QSize mouseHotspotHand WRITE setMouseHotspotHand ) public: TrackContentObjectView( TrackContentObject * tco, TrackView * tv ); @@ -233,6 +237,7 @@ public: void setTextShadowColor( const QColor & c ); void setBBPatternBackground( const QColor & c ); void setGradient( const bool & b ); + void setMouseHotspotHand(const QSize & s); // access needsUpdate member variable bool needsUpdate(); @@ -302,8 +307,10 @@ private: QColor m_textShadowColor; QColor m_BBPatternBackground; bool m_gradient; + QSize m_mouseHotspotHand; // QSize must be used because QPoint isn't supported by property system + bool m_cursorSetYet; - bool m_needsUpdate; + bool m_needsUpdate; inline void setInitialMousePos( QPoint pos ) { m_initialMousePos = pos; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 6a6b0deb1..3f9e04fe6 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -257,6 +257,8 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, m_textShadowColor( 0, 0, 0 ), m_BBPatternBackground( 0, 0, 0 ), m_gradient( true ), + m_mouseHotspotHand( 0, 0 ), + m_cursorSetYet( false ), m_needsUpdate( true ) { if( s_textFloat == NULL ) @@ -268,7 +270,7 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, setAttribute( Qt::WA_OpaquePaintEvent, true ); setAttribute( Qt::WA_DeleteOnClose, true ); setFocusPolicy( Qt::StrongFocus ); - setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); + setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); move( 0, 0 ); show(); @@ -317,6 +319,12 @@ TrackContentObjectView::~TrackContentObjectView() */ void TrackContentObjectView::update() { + if( !m_cursorSetYet ) + { + setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); + m_cursorSetYet = true; + } + if( fixedTCOs() ) { updateLength(); @@ -387,6 +395,11 @@ void TrackContentObjectView::setBBPatternBackground( const QColor & c ) void TrackContentObjectView::setGradient( const bool & b ) { m_gradient = b; } +void TrackContentObjectView::setMouseHotspotHand(const QSize & s) +{ + m_mouseHotspotHand = s; +} + // access needsUpdate member variable bool TrackContentObjectView::needsUpdate() { return m_needsUpdate; } @@ -572,7 +585,7 @@ void TrackContentObjectView::leaveEvent( QEvent * e ) { if( cursor().shape() != Qt::BitmapCursor ) { - setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); + setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); } if( e != NULL ) { From c6a1abe15011dadb1a1e0357632bdec8b7a8c7cb Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Sun, 24 May 2020 13:35:16 +0200 Subject: [PATCH 09/10] Fix #5194: Fix knobs moving too fast (#5360) This PR fixes issues on systems where `QCursor::setPos()` has no effect or is not reliable. These issues included knobs moving to fast on some operating systems. Affected widgets are `Knob` and `LcdSpinBox`. With this PR, on all operating systems, the `setPos` calls are removed and the cursor is not hidden anymore, so the mouse keeps moving normally when changing values of one of the widgets. As now the previous pointer position keeps moving (instead of being reset to the original position using `QCursor::setPos`), the mathematics that translate pointer pixel distance to `Knob`/`LcdSpinBox` value increase have to be changed: * The `Knob` transition function is now linear and uses a new factor. * `LcdSpinBox` now uses float values and saves the current float remainder (this is actually a separate issue revealed by this fix), leading to a fluent, non hanging movement. --- include/Knob.h | 3 +-- include/LcdSpinBox.h | 3 ++- src/gui/widgets/Knob.cpp | 17 ++++++++--------- src/gui/widgets/LcdSpinBox.cpp | 34 ++++++++++++++++++---------------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/Knob.h b/include/Knob.h index d4214334c..e54ed103f 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -174,8 +174,7 @@ private: BoolModel m_volumeKnob; FloatModel m_volumeRatio; - QPoint m_mouseOffset; - QPoint m_origMousePos; + QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent float m_leftOver; bool m_buttonPressed; diff --git a/include/LcdSpinBox.h b/include/LcdSpinBox.h index 0bac3ddc0..38c524c5a 100644 --- a/include/LcdSpinBox.h +++ b/include/LcdSpinBox.h @@ -73,8 +73,9 @@ protected: virtual void mouseDoubleClickEvent( QMouseEvent * _me ); private: + float m_remainder; //!< floating offset of spinbox in [-0.5, 0.5] bool m_mouseMoving; - QPoint m_origMousePos; + QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent int m_displayOffset; void enterValue(); diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index e559d120c..250eb0ad3 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -497,8 +497,8 @@ float Knob::getValue( const QPoint & _p ) { float value; - // arcane mathemagicks for calculating knob movement - value = ( ( _p.y() + _p.y() * qMin( qAbs( _p.y() / 2.5f ), 6.0f ) ) ) / 12.0f; + // knob value increase is linear to mouse movement + value = .4f * _p.y(); // if shift pressed we want slower movement if( gui->mainWindow()->isShiftPressed() ) @@ -587,13 +587,11 @@ void Knob::mousePressEvent( QMouseEvent * _me ) } const QPoint & p = _me->pos(); - m_origMousePos = p; - m_mouseOffset = QPoint(0, 0); + m_lastMousePos = p; m_leftOver = 0.0f; emit sliderPressed(); - QApplication::setOverrideCursor( Qt::BlankCursor ); s_textFloat->setText( displayValue() ); s_textFloat->moveGlobal( this, QPoint( width() + 2, 0 ) ); @@ -618,12 +616,13 @@ void Knob::mousePressEvent( QMouseEvent * _me ) void Knob::mouseMoveEvent( QMouseEvent * _me ) { - if( m_buttonPressed && _me->pos() != m_origMousePos ) + if( m_buttonPressed && _me->pos() != m_lastMousePos ) { - m_mouseOffset = _me->pos() - m_origMousePos; - setPosition( m_mouseOffset ); + // knob position is changed depending on last mouse position + setPosition( _me->pos() - m_lastMousePos ); emit sliderMoved( model()->value() ); - QCursor::setPos( mapToGlobal( m_origMousePos ) ); + // original position for next time is current position + m_lastMousePos = _me->pos(); } s_textFloat->setText( displayValue() ); } diff --git a/src/gui/widgets/LcdSpinBox.cpp b/src/gui/widgets/LcdSpinBox.cpp index 7102f5f6b..07080edc7 100644 --- a/src/gui/widgets/LcdSpinBox.cpp +++ b/src/gui/widgets/LcdSpinBox.cpp @@ -23,6 +23,7 @@ * */ +#include #include #include #include @@ -40,8 +41,9 @@ LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) : LcdWidget( numDigits, parent, name ), IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ), + m_remainder( 0.f ), m_mouseMoving( false ), - m_origMousePos(), + m_lastMousePos(), m_displayOffset( 0 ) { } @@ -52,8 +54,9 @@ LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) : LcdSpinBox::LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name ) : LcdWidget( numDigits, parent, name ), IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ), + m_remainder( 0.f ), m_mouseMoving( false ), - m_origMousePos(), + m_lastMousePos(), m_displayOffset( 0 ) { } @@ -98,8 +101,7 @@ void LcdSpinBox::mousePressEvent( QMouseEvent* event ) event->y() < cellHeight() + 2 ) { m_mouseMoving = true; - m_origMousePos = event->globalPos(); - QApplication::setOverrideCursor( Qt::BlankCursor ); + m_lastMousePos = event->globalPos(); AutomatableModel *thisModel = model(); if( thisModel ) @@ -121,15 +123,20 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event ) { if( m_mouseMoving ) { - int dy = event->globalY() - m_origMousePos.y(); - if( event->modifiers() & Qt::ShiftModifier ) - dy = qBound( -4, dy/4, 4 ); - if( dy > 1 || dy < -1 ) + int dy = event->globalY() - m_lastMousePos.y(); + if( dy ) { - model()->setInitValue( model()->value() - - dy / 2 * model()->step() ); + float fdy = static_cast(dy); + if( event->modifiers() & Qt::ShiftModifier ) { + fdy = qBound( -4.f, fdy/4.f, 4.f ); + } + float floatValNotRounded = + model()->value() + m_remainder - fdy / 2.f * model()->step(); + float floatValRounded = roundf( floatValNotRounded ); + m_remainder = floatValNotRounded - floatValRounded; + model()->setInitValue( floatValRounded ); emit manualChange(); - QCursor::setPos( m_origMousePos ); + m_lastMousePos = event->globalPos(); } } } @@ -142,10 +149,7 @@ void LcdSpinBox::mouseReleaseEvent( QMouseEvent* ) if( m_mouseMoving ) { model()->restoreJournallingState(); - - QCursor::setPos( m_origMousePos ); QApplication::restoreOverrideCursor(); - m_mouseMoving = false; } } @@ -187,5 +191,3 @@ void LcdSpinBox::enterValue() } } - - From 0528a00ccac94e5fccafd5e175371b21451dcf9d Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sun, 24 May 2020 20:59:38 +0200 Subject: [PATCH 10/10] Compensate beat note length when stretching (#5515) * Compensate beat note length when stretching We allow stretching beat notes to normal notes but the length starts from -192 so there is a lag for one whole note before any change is seen. Compensate by setting the oldNote value to 1 when stretching if the note is 0 or below in length. Co-authored-by: Spekular --- src/gui/editors/PianoRoll.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 807696775..3c88b4c43 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1606,6 +1606,11 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) // then resize the note m_action = ActionResizeNote; + for (Note *note : getSelectedNotes()) + { + if (note->oldLength() <= 0) { note->setOldLength(4); } + } + // set resize-cursor QCursor c( Qt::SizeHorCursor ); QApplication::setOverrideCursor( c );