Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global Spacebar Play #7762

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Conversation

regulus79
Copy link
Contributor

@regulus79 regulus79 commented Mar 9, 2025

This PR refactors how the spacebar is handled by the editors and the MainWindow to allow it to play/stop (Shift+Space for play/pause) the last played editor no matter if it is in focus or not.

Changes

  • Editor::togglePlayStop made public to allow MainWindow to call it.
  • Instead of a shortcut, Editor::keyPressEvent was added which checks if the spacebar is pressed and plays/stops the editor.
  • The last used PlayMode is now stored in Song::m_lastPlayMode and is updated whenever the play mode changes, but not when it changes to PlayMode::None.
  • Added a new case to MainWindow::keyPressEvent to handle the spacebar and call togglePlayStop on the right editor.
  • ke->ignore() added to the end of PianoRoll::keyPressEvent, since without it, there were problems with the key event being lost and not triggering the piano roll to play.

New Changes

  • Made PatternEditor use Strong Focus like the rest of the editors. This fixes a bug where the pattern editor sometimes would not play even when it was in focus.
  • Added Shift+Space to play/pause the last played editor.
  • Fixed a bug where pressing space after clicking within the mixer would open a dialog to change the volume of the selected channel.
    • Moved the code which handled the spacebar from MixerView to MixerChannelView, and did some minor refactoring (converting the event filter into just keyPressEvent)
    • Also added e->ignore() to the default case of MixerView::keyPressEvent in order to let the key event be passed up to MainWindow.
    • Added a call to setFocus in MixerChannelView::mousePressEvent so that the MixerChannelView will process still the spacebar key event if you click on it.

I did not implement a global Shift+Space which appears to pause/play the editors. Do you want me to? Done.

Copy link
Collaborator

@qnebra qnebra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works like described. Switching between editors works, space to play in active editor works, space to play in last active editor also works. I don't see issues with using it.

@regulus79
Copy link
Contributor Author

Has anyone experienced issues in this PR with the pattern editor? I recall when implementing it that when I opened an old project, the pattern editor wouldn't play via the space bar until you actually press the play button.

Copy link
Contributor

@rubiefawn rubiefawn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few style suggestions, which should be considered non-blocking.

Comment on lines 1292 to 1309
switch(Engine::getSong()->lastPlayMode())
{
case Song::PlayMode::Song:
getGUI()->songEditor()->togglePlayStop();
break;
case Song::PlayMode::MidiClip:
getGUI()->pianoRoll()->togglePlayStop();
break;
case Song::PlayMode::Pattern:
getGUI()->patternEditor()->togglePlayStop();
break;
case Song::PlayMode::AutomationClip:
getGUI()->automationEditor()->togglePlayStop();
break;
default:
getGUI()->songEditor()->togglePlayStop();
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cases should be on the same indentation level as their switch.

Source: Qt Coding Style since it is not explicitly overidden in the LMMS coding conventions; an example in the LMMS coding conventions; precedent established by existing LMMS code

Suggested change
switch(Engine::getSong()->lastPlayMode())
{
case Song::PlayMode::Song:
getGUI()->songEditor()->togglePlayStop();
break;
case Song::PlayMode::MidiClip:
getGUI()->pianoRoll()->togglePlayStop();
break;
case Song::PlayMode::Pattern:
getGUI()->patternEditor()->togglePlayStop();
break;
case Song::PlayMode::AutomationClip:
getGUI()->automationEditor()->togglePlayStop();
break;
default:
getGUI()->songEditor()->togglePlayStop();
break;
}
switch(Engine::getSong()->lastPlayMode())
{
case Song::PlayMode::Song:
getGUI()->songEditor()->togglePlayStop();
break;
case Song::PlayMode::MidiClip:
getGUI()->pianoRoll()->togglePlayStop();
break;
case Song::PlayMode::Pattern:
getGUI()->patternEditor()->togglePlayStop();
break;
case Song::PlayMode::AutomationClip:
getGUI()->automationEditor()->togglePlayStop();
break;
default:
getGUI()->songEditor()->togglePlayStop();
break;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely wrong to recommend this. Reopening for discussion. No, no no no no. 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For context whenever declaring law, the de facto law that proceeds should be carefully considered. We've never done this. I've never seen this in the wild and I vote we stop recommending this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1487,6 +1487,7 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
}
break;
default:
ke->ignore();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above comment about switch/case indentation is relevant here as well, but formatting this one is optional since you barely touched it.

Copy link
Contributor

@AW1534 AW1534 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this and it works perfectly as described. The code looks good too.

@tresf
Copy link
Member

tresf commented Mar 21, 2025

ke->ignore() added to the end of PianoRoll::keyPressEvent, since without it, there were problems with the key event being lost and not triggering the piano roll to play.

If possible, I'd like this tested against the qt6 branch as well. I had to add an extra ignore() for mouse propagation recently and this PR reminded me of that.

@tresf
Copy link
Member

tresf commented Mar 21, 2025

This has some interesting behavior. This is best shown through a video. Steps:

  1. Load a saved project
  2. Click the title of the song-editor window
  3. Hit Space
  4. Click the title of the pattern-editor window
  5. Hit Space (song-editor plays)
  6. Click an empty space in the pattern-editor window
  7. Hit Space (pattern-editor plays)

(Note: Clicking the pattern editor button in the toolbar and then space will also play the pattern-editor)

There are also some nuanced focus issues that are likely unrelated to this PR, such as hitting spacebar clicks a previously focused button. We may decide to remove certain item focuses when window focus changes, as a separate enhancement.

pattern_behavior

@regulus79
Copy link
Contributor Author

This has some interesting behavior. This is best shown through a video. Steps:

I can also reproduce this issue. It appears to only occur when loading saved projects. I'm not sure why this is happening, so I will have to investigate further.

@regulus79
Copy link
Contributor Author

For some reason after opening a project, the key event is not passed to the pattern editor even when the window is in focus. This does not occur for the Song Editor or the Piano Roll. It also does not occur the first time you open LMMS. However, the issue resolves itself when you interact with the Pattern Editor by either clicking somewhere in the window background.

@regulus79
Copy link
Contributor Author

Alright, I think I've fixed it! It appears that PatternEditor did not share the same setFocusPolicy as the other editors, which somehow caused the issue. I don't really understand how Qt's focus system works, but adding those lines seemed to fix the problem.

I also added a ke->ignore() to the default branch of AutomationEditor::keyPressEvent so that the event will be passed on to Editor::keyPressEvent if it is not processed by the pattern editor. This fixed an issue caused by this PR which I was not aware of, which broke the space bar in the automation editor.

@regulus79
Copy link
Contributor Author

If possible, I'd like this tested against the qt6 branch as well. I had to add an extra ignore() for mouse propagation recently and this PR reminded me of that.

I tested out that branch with this pr merged into it, and it seemed to work fine. I did encounter a segfault when adding an effect, but I can't reproduce it and I don't know if it's related.

@tresf
Copy link
Member

tresf commented Mar 22, 2025

Alright, I think I've fixed it! It appears that PatternEditor did not share the same setFocusPolicy as the other editors, which somehow caused the issue. I don't really understand how Qt's focus system works, but adding those lines seemed to fix the problem.

@regulus79 appears fixed here as well, thanks! This feature is awesome!

This may be unrelated to this PR, but the mixer doesn't work at all (well, I got it to work once but I don't know how)... instead it always tries to change a knob value. I assume this is due to the channel gaining focus, but the only way to reliably remove focus is to open an effect and hit space there. I'm not sure if you'd rather track that issue here or in a separate issue.

What's interesting about this behavior is that it continues to happen even after hiding the mixer. If you hit space, after hiding the mixer, it tries to adjust the mixer volume still. 😆

@regulus79
Copy link
Contributor Author

Before we merge, are you all sure you don't want me to add a global Shift+Space to pause?

@sakertooth
Copy link
Contributor

Before we merge, are you all sure you don't want me to add a global Shift+Space to pause?

I would think the global spacebar would work as a toggle.

@regulus79
Copy link
Contributor Author

I'm asking because that's how it works right now. Normal space does play/stop, shift+space does play/pause.

@sakertooth
Copy link
Contributor

I'm asking because that's how it works right now. Normal space does play/stop, shift+space does play/pause.

Oh wow I wasn't aware lol, I was thinking the global spacebar was play/pause. I think it would be nice if the global spacebar would align with what was chosen in the song editor (i.e., the |<<, <<, and >> options). We should also add that button for the pattern editor too I think.

@sakertooth
Copy link
Contributor

Are we already doing this? Sorry I haven't tested the PR yet.

@regulus79
Copy link
Contributor Author

I think it would be nice if the global spacebar would align with what was chosen in the song editor (i.e., the |<<, <<, and >> options). We should also add that button for the pattern editor too I think.

That is already handled by the editor; this PR just calls the play/stop function. As for the pattern editor, perhaps that would fit in #7794?

@sakertooth
Copy link
Contributor

Okay, so I suppose adding the Shift+Space would be okay for consistency mainly. I'm not really against the addition.

@regulus79
Copy link
Contributor Author

Done!

Copy link
Contributor

@sakertooth sakertooth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make some small formatting adjustments but I won't try and nitpick too much. I'll test the PR and after that we should be good.

Also, I think maybe the PR could use a better title? Something that describes what the commit actually does. Maybe like "Add a global spacebar".

Co-authored-by: Sotonye Atemie <[email protected]>
@sakertooth
Copy link
Contributor

When I press spacebar in the Mixer, it shows this:

image

@regulus79
Copy link
Contributor Author

regulus79 commented Mar 23, 2025

When I press spacebar in the Mixer, it shows this:

That also occurs in master. For some reason when you press spacebar after clicking within the mixer, it thinks you are trying to set the volume of the currently selected channel.

@sakertooth
Copy link
Contributor

sakertooth commented Mar 23, 2025

Any chance we could fix that in here? I think for this feature, the mixer is the most important part.

@regulus79
Copy link
Contributor Author

I mean, I guess I could. But I'm not sure it's really related to this PR.

@sakertooth
Copy link
Contributor

I would think anyone using this feature, this would be somewhat of the first thing they notice. I get it's already on master but I was hoping for this feature to really be useful with the mixer in particular. If its an easy change, I think it would be fine to do it here. Otherwise, if it requires a decent amount of changes from what the PR has right now, then it can wait I guess.

@sakertooth
Copy link
Contributor

sakertooth commented Mar 23, 2025

I would also say its perfectly in scope to be honest: The feature is not really useful in the mixer, which is not something to scoff at.

If we wanted it to be also working in the mixer (which we should IMO), then if we don't do it here and in a follow up PR, the PRs/objectives end up being quite related actually.

@regulus79
Copy link
Contributor Author

Alright, it should be fixed!

I had to remove the handling of the space key event from MixerView and add it to keyPressEvent in MixerChannelView so that it would only be triggered if the user has the channel in focus. Also, it appeared that MixerChannelView was using an eventFilter to handle key press events, so I converted that to be keyPressEvent to be consistent.

@regulus79
Copy link
Contributor Author

Wait wait wait hold on a second I did something wrong

@regulus79
Copy link
Contributor Author

Yeah, so just like PianoRoll and AutomationEditor, the MixerView's keyPressEvent function did not set ke->ignore() by default if it did nothing, which meant the key event was not getting passed up to MainWindow. It should be fixed now.

@sakertooth
Copy link
Contributor

Great, this is really handy now! :)

@regulus79
Copy link
Contributor Author

Wait a minute again... somehow I broke the spacebar to enter the volume. I should really be doing more testing before doing git push.

Unless we're okay with losing that functionality? If we want spacebar to always mean play/stop/pause, then maybe it would make sense to remove this shortcut/change it to something else?

@sakertooth
Copy link
Contributor

Unless we're okay with losing that functionality? If we want spacebar to always mean play/stop/pause, then maybe it would make sense to remove this shortcut/change it to something else?

I wasn't even initially aware that spacebar in the Mixer opened the volume dialog. IMO, since we can already open the dialog by double clicking, opening it with the spacebar might be redundant. But yeah that's just my opinion. It's a hard decision and it needs more input from other devs/the community.

@regulus79
Copy link
Contributor Author

It's okay, I fixed it (for realsies this time :D)

Basically the MixerChannelView was not automatically getting focus when you click on it (except when renaming the channel, since in that case the lineEdit child had focus), so I added a call to setFocus in MixerChannelView::mousePressEvent which seemed to do the trick. I hope I tested it well enough this time.

@tresf
Copy link
Member

tresf commented Mar 24, 2025

Unless we're okay with losing that functionality? If we want spacebar to always mean play/stop/pause, then maybe it would make sense to remove this shortcut/change it to something else?

I wasn't even initially aware that spacebar in the Mixer opened the volume dialog. IMO, since we can already open the dialog by double clicking, opening it with the spacebar might be redundant. But yeah that's just my opinion. It's a hard decision and it needs more input from other devs/the community.

I thought about this too... It would likely become a future accessibility/robots issue. I'm sure we have plenty of these, but that's the first thing that comes to mind especially when we're talking about automating the GUI as a futuremap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants