Support text-input-v3 cursor position and position the overlay mode input panel within the screen.
This commit is contained in:
parent
7a270b5d78
commit
e71fe9ba79
4 changed files with 89 additions and 58 deletions
|
@ -18,6 +18,7 @@
|
|||
#include <KWaylandServer/seat_interface.h>
|
||||
#include <KWaylandServer/surface_interface.h>
|
||||
#include <KWaylandServer/textinput_v2_interface.h>
|
||||
#include <KWaylandServer/textinput_v3_interface.h>
|
||||
|
||||
using namespace KWaylandServer;
|
||||
|
||||
|
@ -90,11 +91,40 @@ void KWin::InputPanelV1Client::reposition()
|
|||
}
|
||||
} break;
|
||||
case Overlay: {
|
||||
auto textClient = waylandServer()->findClient(waylandServer()->seat()->focusedTextInputSurface());
|
||||
auto textInput = waylandServer()->seat()->textInputV2();
|
||||
if (textClient && textInput) {
|
||||
const auto cursorRectangle = textInput->cursorRectangle();
|
||||
moveResize({textClient->pos() + textClient->clientPos() + cursorRectangle.bottomLeft(), surface()->size()});
|
||||
auto textInputSurface = waylandServer()->seat()->focusedTextInputSurface();
|
||||
auto textClient = waylandServer()->findClient(textInputSurface);
|
||||
QRect cursorRectangle;
|
||||
auto textInputV2 = waylandServer()->seat()->textInputV2();
|
||||
if (textInputV2 && textInputV2->isEnabled() && textInputV2->surface() == textInputSurface) {
|
||||
cursorRectangle = textInputV2->cursorRectangle();
|
||||
}
|
||||
auto textInputV3 = waylandServer()->seat()->textInputV3();
|
||||
if (textInputV3 && textInputV3->isEnabled() && textInputV3->surface() == textInputSurface) {
|
||||
cursorRectangle = textInputV3->cursorRectangle();
|
||||
}
|
||||
if (textClient) {
|
||||
cursorRectangle.translate(textClient->pos() + textClient->clientPos());
|
||||
const QRect screen = Workspace::self()->clientArea(PlacementArea, cursorRectangle.bottomLeft(), 0);
|
||||
|
||||
// Reuse the similar logic like xdg popup
|
||||
QRect popupRect(popupOffset(cursorRectangle, Qt::TopEdge | Qt::LeftEdge, Qt::RightEdge | Qt::BottomEdge, surface()->size()), surface()->size());
|
||||
|
||||
if (popupRect.left() < screen.left()) {
|
||||
popupRect.moveLeft(screen.left());
|
||||
}
|
||||
if (popupRect.right() > screen.right()) {
|
||||
popupRect.moveRight(screen.right());
|
||||
}
|
||||
if (popupRect.top() < screen.top() || popupRect.bottom() > screen.bottom()) {
|
||||
auto flippedPopupRect =
|
||||
QRect(popupOffset(cursorRectangle, Qt::BottomEdge | Qt::LeftEdge, Qt::RightEdge | Qt::TopEdge, surface()->size()), surface()->size());
|
||||
|
||||
// if it still doesn't fit we should continue with the unflipped version
|
||||
if (flippedPopupRect.top() >= screen.top() || flippedPopupRect.bottom() <= screen.bottom()) {
|
||||
popupRect.moveTop(flippedPopupRect.top());
|
||||
}
|
||||
}
|
||||
moveResize(popupRect);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -203,6 +203,58 @@ qreal qPainterEffectiveDevicePixelRatio(const QPainter *painter)
|
|||
return std::max(qreal(1), painter->device()->devicePixelRatioF());
|
||||
}
|
||||
|
||||
QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSize popupSize)
|
||||
{
|
||||
QPoint anchorPoint;
|
||||
switch (anchorEdge & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
case Qt::LeftEdge:
|
||||
anchorPoint.setX(anchorRect.x());
|
||||
break;
|
||||
case Qt::RightEdge:
|
||||
anchorPoint.setX(anchorRect.x() + anchorRect.width());
|
||||
break;
|
||||
default:
|
||||
anchorPoint.setX(qRound(anchorRect.x() + anchorRect.width() / 2.0));
|
||||
}
|
||||
switch (anchorEdge & (Qt::TopEdge | Qt::BottomEdge)) {
|
||||
case Qt::TopEdge:
|
||||
anchorPoint.setY(anchorRect.y());
|
||||
break;
|
||||
case Qt::BottomEdge:
|
||||
anchorPoint.setY(anchorRect.y() + anchorRect.height());
|
||||
break;
|
||||
default:
|
||||
anchorPoint.setY(qRound(anchorRect.y() + anchorRect.height() / 2.0));
|
||||
}
|
||||
|
||||
// calculate where the top left point of the popup will end up with the applied gravity
|
||||
// gravity indicates direction. i.e if gravitating towards the top the popup's bottom edge
|
||||
// will next to the anchor point
|
||||
QPoint popupPosAdjust;
|
||||
switch (gravity & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
case Qt::LeftEdge:
|
||||
popupPosAdjust.setX(-popupSize.width());
|
||||
break;
|
||||
case Qt::RightEdge:
|
||||
popupPosAdjust.setX(0);
|
||||
break;
|
||||
default:
|
||||
popupPosAdjust.setX(qRound(-popupSize.width() / 2.0));
|
||||
}
|
||||
switch (gravity & (Qt::TopEdge | Qt::BottomEdge)) {
|
||||
case Qt::TopEdge:
|
||||
popupPosAdjust.setY(-popupSize.height());
|
||||
break;
|
||||
case Qt::BottomEdge:
|
||||
popupPosAdjust.setY(0);
|
||||
break;
|
||||
default:
|
||||
popupPosAdjust.setY(qRound(-popupSize.height() / 2.0));
|
||||
}
|
||||
|
||||
return anchorPoint + popupPosAdjust;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifndef KCMRULES
|
||||
|
|
|
@ -280,6 +280,8 @@ private:
|
|||
int m_capacity = 10;
|
||||
};
|
||||
|
||||
KWIN_EXPORT QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSize popupSize);
|
||||
|
||||
} // namespace
|
||||
|
||||
// Must be outside namespace
|
||||
|
|
|
@ -1865,59 +1865,6 @@ bool XdgPopupClient::hasTransientPlacementHint() const
|
|||
return true;
|
||||
}
|
||||
|
||||
static QPoint popupOffset(const QRect &anchorRect, const Qt::Edges anchorEdge,
|
||||
const Qt::Edges gravity, const QSize popupSize)
|
||||
{
|
||||
QPoint anchorPoint;
|
||||
switch (anchorEdge & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
case Qt::LeftEdge:
|
||||
anchorPoint.setX(anchorRect.x());
|
||||
break;
|
||||
case Qt::RightEdge:
|
||||
anchorPoint.setX(anchorRect.x() + anchorRect.width());
|
||||
break;
|
||||
default:
|
||||
anchorPoint.setX(qRound(anchorRect.x() + anchorRect.width() / 2.0));
|
||||
}
|
||||
switch (anchorEdge & (Qt::TopEdge | Qt::BottomEdge)) {
|
||||
case Qt::TopEdge:
|
||||
anchorPoint.setY(anchorRect.y());
|
||||
break;
|
||||
case Qt::BottomEdge:
|
||||
anchorPoint.setY(anchorRect.y() + anchorRect.height());
|
||||
break;
|
||||
default:
|
||||
anchorPoint.setY(qRound(anchorRect.y() + anchorRect.height() / 2.0));
|
||||
}
|
||||
|
||||
// calculate where the top left point of the popup will end up with the applied gravity
|
||||
// gravity indicates direction. i.e if gravitating towards the top the popup's bottom edge
|
||||
// will next to the anchor point
|
||||
QPoint popupPosAdjust;
|
||||
switch (gravity & (Qt::LeftEdge | Qt::RightEdge)) {
|
||||
case Qt::LeftEdge:
|
||||
popupPosAdjust.setX(-popupSize.width());
|
||||
break;
|
||||
case Qt::RightEdge:
|
||||
popupPosAdjust.setX(0);
|
||||
break;
|
||||
default:
|
||||
popupPosAdjust.setX(qRound(-popupSize.width() / 2.0));
|
||||
}
|
||||
switch (gravity & (Qt::TopEdge | Qt::BottomEdge)) {
|
||||
case Qt::TopEdge:
|
||||
popupPosAdjust.setY(-popupSize.height());
|
||||
break;
|
||||
case Qt::BottomEdge:
|
||||
popupPosAdjust.setY(0);
|
||||
break;
|
||||
default:
|
||||
popupPosAdjust.setY(qRound(-popupSize.height() / 2.0));
|
||||
}
|
||||
|
||||
return anchorPoint + popupPosAdjust;
|
||||
}
|
||||
|
||||
QRect XdgPopupClient::transientPlacement(const QRect &bounds) const
|
||||
{
|
||||
const XdgPositioner positioner = m_shellSurface->positioner();
|
||||
|
|
Loading…
Reference in a new issue