Keyboard shortcut/hotkey for actions within a dock area plugin
I have a plugin with pluginType: "dock"
that has some buttons in it's UI.
Is there any way to allow keyboard shortcuts for the button's actions?
I read bazhenoff's answer in https://musescore.org/en/node/314156
His suggestion is to have a focused key listener area in the plugin:
Item {
focus: true
Keys.onPressed: {
console.log("Key press in key area detected: " + event.key)
}
}
It's quite close to what I need but there is one problem: When I press the shortcut to open my plugin (as a shortcut leader key), it always starts a new instance of my plugin instead of focusing it. So I have no way to focus my plugin with a keyboard shortcut.
Is there a way/work around?
Comments
1) Yes, application-level shortcuts can be defined using
Shortcut
QML type withQt.ApplicationShortcut
scope:The format which is accepted by
sequence
property is described, for example, here as well as in that property documentation.2) Requesting keyboard focus for a plugin is not that straightforward but is doable. The issue is that a plugin is QML item while the entire application is QtWidgets-based, and in order to embed plugin view into the application the plugin is actually rendered in a separate window. Therefore in order to focus a plugin you should activate that window first. This can be done in QML using
Window
type.Window.window
attached property:requestActivate()
call:forceActiveFocus()
on it:In reply to 1) Yes, there is a way to… by dmitrio95
Thank you very much for this detailed answer!
The application shortcuts already work quite well for me.
Do you happen to know, how I can activate my existing plugin instead of starting a another instance? I guess
onRun
I could find the plugin window by id and if it existsfoundWindow.requestActivate(); Qt.quit();
?In reply to Thank you very much for this… by nurfz
I don't think it is possible to find another instance of a plugin right now. This would most probably require some changes in the plugin engine of MuseScore itself.
In reply to I don't think it is possible… by dmitrio95
You can write a settings flag when opening/running your plugin and check for that setting in subsequent runs to at least shut duplicates down.
But there is indeed no way to then also put the focus at the previous instance.
In reply to You can write a settings… by jeetee
Is that safe? I mean if the plugin crashes or is for some reason not shut down correctly, it cannot be started anymore. At least not without restarting MuseScore, right?
In reply to Is that safe? I mean if the… by nurfz
Possibly..
Don't write plugins that crash ;-)
Consider combining it with a timestamp perhaps
In reply to I don't think it is possible… by dmitrio95
Well, it turns out I was not fully correct. As all plugins are currently executed by the same instance of QML engine, it is possible to pass messages between them using QML singleton types (see https://doc.qt.io/qt-5/qtqml-modules-qmldir.html). I attach an example of such plugin to this comment: you can launch several instances of this plugin and see how changing text in one plugin instance changes the displayed text in all the launched plugin instances. Apparently this mechanism can be used to trigger focus request in the relevant plugin instance.
The issue is, however, that the new instance of such plugin would also have to somehow close itself. As it has been described in this comment,
Qt.quit()
isn't really a good option here since it would force all plugin instances to quit, and dock plugins do not seem to have an option to close only current instance of a plugin without closing all the other displayed plugin instances as well. So in this case the plugin would be able to focus the previous plugin instance but the new instance would still be launched and displayed.Maybe the solution would be to add a dedicated
quit()
method to plugin API that would allow to close exactly one plugin instance (if we still have some time before 3.6 release). But other than that there doesn't seem to be a good way to get this working.In reply to Well, it turns out I was not… by dmitrio95
Thanks for sharing! Well, not as easy and neat as a single-file plugin. But a good way to communicate with other instances.