-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Saving a project forces mixer/automation/* windows to background #2087
Comments
What's more, this seems to also happen whenever LMMS autosaves - I left the window idle with the mixer on top and every minute on the dot the mixer would be sent to the background (and I would recall it to the foreground manually). Again, this only happened when I had another window inside LMMS maximized. FURTHERMORE, if another application has focus during the autosave, LMMS forces itself to the foreground (I'm using XFCE as my desktop environment), but again, only if one of the LMMS sub-windows is maximized. This has been plaguing me for weeks, so I'm glad I now know a workaround and have narrowed down the cause. |
I think the first spot where this happens is here: Something in those So, we end up here: https://github.com/LMMS/lmms/blob/master/src/gui/MainWindow.cpp#L696, which I guess is a workaround for |
fyi: not reproduceable on 1.1.3 win 32 |
Maybe every window should store its geometry every time it gets a resize or move event and isn't maximized or minimized. And then save that without needing the maximization trickery. |
Ohhh. Interesting. So the purpose of the lines around 696 in MainWindow.cpp is to also save the non-maximized/minimized geometry so that pressing the window's restore button will work the same now as when you load the file at a later time. Perhaps there's a variant of Edit: the documentation for setWindowState says that it will cause the window to be hidden for some reason. Thus a followup call to show() is required, which I think wouldn't fix anything. Edit 2: setWindowState does not cause the window to be hidden on my system. |
The other option is to enumerate the At the very least, we can call Edit: |
By the way, the normalGeometry() issue seems to be a relatively obscure bug, only affecting X11 users when the window is maximized by the user and not by a Qt call (although my tests indicate that it the issue still occurs when the window is maximized by Qt code) (bug report). A user in that bug report suggests doing what amounts to your suggestion of storing the size manually. I did some digging to try to figure out how Turns out that if you replace all the show()/hide() stuff in MainWindow::saveWidgetState() with calls like: if( mined || maxed ) {
_w->setWindowState(_w->windowState() & ~(Qt::WindowMinimized
| Qt::WindowMaximized
| Qt::WindowActive));
}
...
if (maxed)
{
_w->setWindowState((_w->windowState() | Qt::WindowMaximized) & ~Qt::WindowActive);
}
if (mined)
{
_w->setWindowState((_w->windowState() | Qt::WindowMinimized) & ~Qt::WindowActive);
} ... then you can achieve the exact same behavior as currently, including the improper window reordering - even if you comment out the last two if statements. I tracked down Qt's setWindowState function for X11 here. For the case of a restore operation (as in the above), it's pretty simple. If basically amounts to this: <Save the old state>
<Store the new state as a member variable.>
qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
if (needShow) // needShow should be computed as false based on me mentally following the code flow
show();
if (newstate & Qt::WindowActive) // WindowActive was set to false in the attribute list
activateWindow();
QWindowStateChangeEvent e(oldstate);
QApplication::sendEvent(this, &e); There are of course some more function calls used to determine control flow, but none of them should cause any state changes. It basically narrows the issue down to either the It is worth noting that although changing the code to So yeah, I think the only proper fix is to track the non-maximized geometry ourselves, as @softrabbit suggested. Sadly, I think this requires subclassing a bunch of Widgets from a new custom class that tracks this information. The only other feasible option is a global event filter with a map that retains this information, or creating some slots when these widgets are created for whatever slot gets fired when a widget's geometry is changed, but I think the simpler option should be favored here even if it requires editing more code. |
I did a bit of toying around with a solution today. I'm not intimately familiar with Qt, but it turns out that all of the LMMS subwindows are created by calls to So the easiest/best way to fix this is likely to add a new class, Lastly, modify the logic inside of MainWindow::saveWidgetState. It currently has a block that looks like this: if( _w->widget()->parentWidget() != NULL &&
_w->widget()->parentWidget()->inherits( "QMdiSubWindow" ) )
{
_w = _w->parentWidget();
} It should only take some minor modifications to make it also use some custom accessors when we inherit from "SubWindow" in place of Qt's x(), y(), etc. I should hopefully have something ready within a day or two. |
Proposed fix via PR #2103. |
Fix for #2087: Issues with saving projects in X11 when one subwindow is maximized
Closed via #2103. Hurray! |
This only occurs when you have one of the windows in LMMS' maximized, as shown in the gif below (most commonly, people do this with the song editor, but you can do it with the piano roll and automation editors too).
In this case, if I have any other window, like the Mixer, in the foreground and I hit Ctrl+S (or save manually via the file menu), such windows will be sent to the background. It can be an annoyance.
It is interesting to note that this still occurs if the automation editor or piano roll is maximized instead of the song editor, but there is not issue if no window is maximized.
The text was updated successfully, but these errors were encountered: