-
Notifications
You must be signed in to change notification settings - Fork 26
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
Autocomplete pop-ups appearing on wrong monitor in multi-headed systems #77
Comments
On my Mac it simply works. I will try to change it, so it uses screenAt |
This is pretty strange.. The TextEditorAutoCompleteComponent uses the TextEditorComponent as Parent Component. Do you know what methods I use are conflicting or deprecated? (I don't use availableGeometry) |
QWidget::mapToGlobal |
In which source file is this used? I cannot find it with grep in the sources of edbee-lib. |
Well you are using QDesktopWidget::availableGeometry(...) and both forms that take an argument (a pointer to a widget OR a screen number) were declared obsolete I seen in Qt 5.11.0 ... In the situation I think I was seeing that call (in two places) returning something like Actually running with some debug code in place: void TextEditorAutoCompleteComponent::positionWidgetForCaretOffset(int offset)
{
qDebug() << "TextEditorAutoCompleteComponent::positionWidgetForCaretOffset(" << offset << ") :";
// find the caret position
TextRenderer* renderer = controller()->textRenderer();
qDebug() << " Viewport (X,Y)" << controller()->textRenderer()->viewportX() << "," << controller()->textRenderer()->viewportY();
int y = renderer->yPosForOffset(offset) - controller()->textRenderer()->viewportY(); //offset the y position based on how far scrolled down the editor is
int x = renderer->xPosForOffset(offset) - controller()->textRenderer()->viewportX() + marginComponentRef_->widthHint() - 3; //adjusts x position based on scrollbars, line-number, and position in line
qDebug() << " X:" << x << " Y:" << y;
QPoint newLoc = editorComponentRef_->parentWidget()->parentWidget()->mapToGlobal(QPoint(x, y));
//We want to constrain the list to only show within the available screen space
QRect screen = QApplication::desktop()->availableGeometry(this);
qDebug().nospace().noquote() << " screen.left: " << screen.left() << " screen.top: " << screen.top() << " screen.width: " << screen.width() << " screen.height: " << screen.height() << " screen.bottom: " << screen.bottom();
qDebug() << " Initial newLoc (X,Y)" << newLoc.x() << "," << newLoc.y() << ")";
newLoc.setX(qMax(screen.left(), newLoc.x())); //constrain the origin of the list to the leftmost pixel
newLoc.setY(qMax(screen.top(), newLoc.y())); //constrain the origin of the list to the topmost pixel
newLoc.setX(qMin(screen.x() + screen.width() - menuRef_->width(), newLoc.x())); //ensure that the entire width of the list can be shown to the right
if( newLoc.y() + menuRef_->height() > screen.bottom() ){ //if the list could go below the bottom, draw above
newLoc.setY(qMin(newLoc.y(), screen.bottom()) - menuRef_->height()); //positions the list above the word
} else {
newLoc.setY(newLoc.y() + renderer->lineHeight()); //places it below the line, as normal
}
qDebug() << " Adjusted newLoc (X,Y)" << newLoc.x() << "," << newLoc.y() << ")";
menuRef_->move(newLoc.x(), newLoc.y());
} With the parent window in the lower screen (and the popup in the correct place) I got:
However with the parent window in the upper screen I got:
To me the value of |
Oh, humblest, grovelling apologies - it is @dicene 's fork (https://github.com/dicene/edbee-lib) that has improved your code to the extent that it is broken |
Haha no problem! I guess that positioning the widget should be kept relative top the parent window. I don't think it's required to know which screen it's on.. |
And a fix (at least for Qt 5.10.0 and later) is proposed at https://github.com/dicene/edbee-lib/pull/1 .
... it seems that should be above or below the cursor is dependent on whereabouts on the screen the cursor is and that needs to know which screen it is being shown on to get the range of usable coordinates! |
As noted in the comment above
TextEditorAutoCompleteComponent::positionWidgetForCaretOffset(int offset)
which says:there is a blooming great flaw in the code at least on X11 in a Linux environment with more than one monitor participating in a virtual desktop.
Whilst using Mudlet's version of edbee-lib (as revised by Dicene - possibly including some stuff from #75 that may not have been merged here) I found out that for my setup, comprising two 1680x1050 monitors in a vertical arrangement such that the upper monitor occupies (0,0) to (1679,1049) in Qt and X11 pixel coordinate terms and the lower (primary) one occupies (0,1050) to (1679,2099):
an auto-completion popup for a widget in the upper screen gets forced down to the lower screen, although doing the same when the widget is on the lower screen appears in the correct location:
The screen-shots do not show quite how bad this looks because the two separate screen areas are not so obviously separated in them compared to in real-life - the upper screen contains the application's main widow maximised so that the blue background represents that area that is on the other, lower, monitor.
I guess that the limits used to detect whether the menu needs to popup or popdown needs further revision to consider the correct limits when a virtual desktop is in use - because that will change how some of the screen geometry methods return values for the whole desktop rather than the specific screen on which a widget is drawn. I added some debugging code to report some of the details in each of the above two cases but I could not get my brain wrapped around how to improve the code to use the right limits and then apply the right correction - but I believe the method I mentioned at the top of this issue is the guilty culprit...! 🤔
The text was updated successfully, but these errors were encountered: