Remove embedded implementation of the Virtual Keyboard

This commit is contained in:
Aleix Pol 2020-07-27 21:30:49 +02:00 committed by Aleix Pol Gonzalez
parent 7aabd45df9
commit 3733e3e77f
8 changed files with 35 additions and 213 deletions

View file

@ -124,6 +124,11 @@ NET::WindowType InputPanelV1Client::windowType(bool, int) const
return NET::Utility; return NET::Utility;
} }
QRect InputPanelV1Client::inputGeometry() const
{
return surface()->input().boundingRect().translated(pos());
}
void InputPanelV1Client::hideClient(bool hide) void InputPanelV1Client::hideClient(bool hide)
{ {
m_visible = !hide; m_visible = !hide;
@ -135,6 +140,7 @@ void InputPanelV1Client::hideClient(bool hide)
reposition(); reposition();
addRepaintFull(); addRepaintFull();
Q_EMIT windowShown(this); Q_EMIT windowShown(this);
autoRaise();
} }
} }

View file

@ -55,6 +55,7 @@ public:
void setNoBorder(bool /*set*/) override {} void setNoBorder(bool /*set*/) override {}
NET::WindowType windowType(bool /*direct*/, int /*supported_types*/) const override; NET::WindowType windowType(bool /*direct*/, int /*supported_types*/) const override;
void debug(QDebug & stream) const override; void debug(QDebug & stream) const override;
QRect inputGeometry() const override;
private: private:
void showTopLevel(KWaylandServer::OutputInterface *output, KWaylandServer::InputPanelSurfaceV1Interface::Position position); void showTopLevel(KWaylandServer::OutputInterface *output, KWaylandServer::InputPanelSurfaceV1Interface::Position position);

View file

@ -246,9 +246,6 @@ bool InternalClient::isLockScreen() const
bool InternalClient::isInputMethod() const bool InternalClient::isInputMethod() const
{ {
if (m_internalWindow) {
return m_internalWindow->property("__kwin_input_method").toBool();
}
return false; return false;
} }

View file

@ -99,15 +99,6 @@ void Integration::initialize()
} }
} }
); );
connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this,
[] {
if (qApp->inputMethod()->isVisible()) {
if (QWindow *w = VirtualKeyboard::self()->inputPanel()) {
QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason);
}
}
}
);
} }
} }

View file

@ -1,3 +1,3 @@
install(DIRECTORY outline/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/outline) install(DIRECTORY outline/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/outline)
install(DIRECTORY onscreennotification/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/onscreennotification) install(DIRECTORY onscreennotification/plasma DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME}/onscreennotification)
install(DIRECTORY virtualkeyboard DESTINATION ${DATA_INSTALL_DIR}/${KWIN_NAME})

View file

@ -1,61 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
import QtQuick 2.0
import QtQuick.Controls 2.3
import QtQuick.VirtualKeyboard 2.1
import org.kde.kirigami 2.5 as Kirigami
Item {
id: window
property real adjustment: 0
property real adjustmentFactor: 0.0
InputPanel {
id: inputPanel
objectName: "inputPanel"
width: parent.width - parent.width * parent.adjustmentFactor
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
}
//NOTE: ToolButton for some reasons breaks the virtual keyboard loading on Plasma Mobile
Button {
id: resizeButton
visible: !Kirigami.Settings.isMobile //don't show on handheld devices
flat: true
display: AbstractButton.IconOnly
icon.name: "transform-scale"
icon.color: "white"
down: mouseArea.pressed
anchors {
right: inputPanel.right
top: inputPanel.top
}
MouseArea {
id: mouseArea
property real startPoint: 0
anchors.fill: parent
onPressed: {
startPoint = mouse.x;
}
onPositionChanged: {
window.adjustment -= (mouse.x - startPoint);
window.adjustmentFactor = Math.min(Math.max(window.adjustment / window.width, 0.0), 0.66);
startPoint = mouse.x;
}
}
}
// this property assignment is done here to not break 5.14.x qtvirtualkeyboard
// TODO: Move it to InputPanel when we depend on 5.15
Component.onCompleted: {
if (inputPanel.hasOwnProperty("desktopPanel")) {
inputPanel.desktopPanel = true;
}
}
}

View file

@ -63,20 +63,6 @@ VirtualKeyboard::~VirtualKeyboard() = default;
void VirtualKeyboard::init() void VirtualKeyboard::init()
{ {
// TODO: need a shared Qml engine
qCDebug(KWIN_VIRTUALKEYBOARD) << "Initializing window";
m_inputWindow.reset(new QQuickView(nullptr));
m_inputWindow->setFlags(Qt::FramelessWindowHint);
m_inputWindow->setGeometry(screens()->geometry(screens()->current()));
m_inputWindow->setResizeMode(QQuickView::SizeRootObjectToView);
m_inputWindow->setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME "/virtualkeyboard/main.qml"))));
if (m_inputWindow->status() != QQuickView::Status::Ready) {
qCWarning(KWIN_VIRTUALKEYBOARD) << "window not ready yet";
m_inputWindow.reset();
return;
}
m_inputWindow->setProperty("__kwin_input_method", true);
connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::aboutToLock, this, &VirtualKeyboard::hide); connect(ScreenLockerWatcher::self(), &ScreenLockerWatcher::aboutToLock, this, &VirtualKeyboard::hide);
if (waylandServer()) { if (waylandServer()) {
@ -118,28 +104,22 @@ void VirtualKeyboard::init()
t2->create(); t2->create();
auto inputPanel = waylandServer()->display()->createInputPanelInterface(this); auto inputPanel = waylandServer()->display()->createInputPanelInterface(this);
connect(inputPanel, &InputPanelV1Interface::inputPanelSurfaceAdded, this, [this, inputPanel] (InputPanelSurfaceV1Interface *surface) { connect(inputPanel, &InputPanelV1Interface::inputPanelSurfaceAdded, this, [this] (InputPanelSurfaceV1Interface *surface) {
m_inputClient = waylandServer()->createInputPanelClient(surface); m_inputClient = waylandServer()->createInputPanelClient(surface);
auto refreshFrame = [this] { auto refreshFrame = [this] {
const QRect inputGeometry = m_inputClient->surface()->input().boundingRect(); if (!m_trackedClient) {
if (!m_trackedClient || inputGeometry.isEmpty()) {
return; return;
} }
m_trackedClient->setVirtualKeyboardGeometry(inputGeometry);
m_trackedClient->setVirtualKeyboardGeometry(m_inputClient ? m_inputClient->inputGeometry() : QRect());
}; };
connect(surface->surface(), &SurfaceInterface::inputChanged, this, refreshFrame); connect(surface->surface(), &SurfaceInterface::inputChanged, this, refreshFrame);
connect(surface->surface(), &QObject::destroyed, this, [this] {
connect(surface->surface(), &SurfaceInterface::inputChanged, this, refreshFrame); if (m_trackedClient) {
connect(this, &VirtualKeyboard::hide, m_inputClient, [this] { m_trackedClient->setVirtualKeyboardGeometry({});
m_inputClient->hideClient(true); }
});
connect(this, &VirtualKeyboard::show, m_inputClient, [this] {
m_inputClient->hideClient(false);
});
connect(surface->surface(), &SurfaceInterface::unmapped, this, [this, inputPanel, surface] {
m_inputClient->destroyClient();
inputPanel->inputPanelSurfaceAdded(surface);
}); });
updateInputPanelState();
refreshFrame(); refreshFrame();
}); });
@ -182,7 +162,7 @@ void VirtualKeyboard::init()
adoptInputMethodContext(); adoptInputMethodContext();
} else { } else {
waylandServer()->inputMethod()->sendDeactivate(); waylandServer()->inputMethod()->sendDeactivate();
Q_EMIT hide(); hide();
} }
qApp->inputMethod()->update(Qt::ImQueryAll); qApp->inputMethod()->update(Qt::ImQueryAll);
}); });
@ -197,7 +177,6 @@ void VirtualKeyboard::init()
m_trackedClient = newClient; m_trackedClient = newClient;
} }
updateInputPanelState(); updateInputPanelState();
} else { } else {
m_waylandShowConnection = QMetaObject::Connection(); m_waylandShowConnection = QMetaObject::Connection();
@ -211,26 +190,21 @@ void VirtualKeyboard::init()
} }
); );
} }
m_inputWindow->installEventFilter(this);
connect(Workspace::self(), &Workspace::destroyed, this,
[this] {
m_inputWindow.reset();
}
);
m_inputWindow->setColor(Qt::transparent);
m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect());
connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, m_inputWindow.data(),
[this] {
if (!m_inputWindow) {
return;
}
m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect());
}
);
connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this, &VirtualKeyboard::updateInputPanelState); connect(qApp->inputMethod(), &QInputMethod::visibleChanged, this, &VirtualKeyboard::updateInputPanelState);
}
connect(m_inputWindow->rootObject(), &QQuickItem::childrenRectChanged, this, &VirtualKeyboard::updateInputPanelState); void VirtualKeyboard::show()
{
auto t = waylandServer()->seat()->focusedTextInput();
if (t) {
Q_EMIT t->enabledChanged();
}
}
void VirtualKeyboard::hide()
{
waylandServer()->inputMethod()->sendDeactivate();
updateInputPanelState();
} }
void VirtualKeyboard::setEnabled(bool enabled) void VirtualKeyboard::setEnabled(bool enabled)
@ -373,57 +347,8 @@ void VirtualKeyboard::updateInputPanelState()
return; return;
} }
if (m_inputWindow) { m_trackedClient->setVirtualKeyboardGeometry(m_inputClient ? m_inputClient->inputGeometry() : QRect());
const bool inputPanelHasBeenClosed = m_inputWindow->isVisible() && !qApp->inputMethod()->isVisible(); t->setInputPanelState(m_inputClient && m_inputClient->isShown(false), QRect(0, 0, 0, 0));
if (inputPanelHasBeenClosed && m_floodTimer->isActive()) {
return;
}
m_floodTimer->start();
m_inputWindow->setVisible(qApp->inputMethod()->isVisible());
if (qApp->inputMethod()->isVisible()) {
m_inputWindow->setMask(m_inputWindow->rootObject()->childrenRect().toRect());
}
if (m_inputWindow->isVisible() && m_trackedClient && m_inputWindow->rootObject()) {
const QRect inputPanelGeom = m_inputWindow->rootObject()->childrenRect().toRect().translated(m_inputWindow->geometry().topLeft());
m_trackedClient->setVirtualKeyboardGeometry(inputPanelGeom);
t->setInputPanelState(true, QRect(0, 0, 0, 0));
} else {
if (inputPanelHasBeenClosed && m_trackedClient) {
m_trackedClient->setVirtualKeyboardGeometry(QRect());
}
t->setInputPanelState(false, QRect(0, 0, 0, 0));
}
}
if (m_inputClient) {
m_trackedClient->setVirtualKeyboardGeometry(m_inputClient->frameGeometry());
t->setInputPanelState(true, QRect(0, 0, 0, 0));
}
}
void VirtualKeyboard::show()
{
if (m_inputWindow.isNull() || !m_enabled) {
return;
}
m_inputWindow->setGeometry(screens()->geometry(screens()->current()));
qApp->inputMethod()->show();
}
void VirtualKeyboard::hide()
{
if (m_inputWindow.isNull()) {
return;
}
m_inputWindow->hide();
qApp->inputMethod()->hide();
} }
bool VirtualKeyboard::event(QEvent *e) bool VirtualKeyboard::event(QEvent *e)
@ -596,37 +521,4 @@ bool VirtualKeyboard::event(QEvent *e)
return QObject::event(e); return QObject::event(e);
} }
bool VirtualKeyboard::eventFilter(QObject *o, QEvent *e)
{
if (o != m_inputWindow.data() || !m_inputWindow->isVisible()) {
return false;
}
if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
QKeyEvent *event = static_cast<QKeyEvent*>(e);
if (event->nativeScanCode() == 0) {
// this is a key composed by the virtual keyboard - we need to send it to the client
const auto sym = input()->keyboard()->xkb()->fromKeyEvent(event);
if (sym != 0) {
if (waylandServer()) {
auto t = waylandServer()->seat()->focusedTextInput();
if (t && t->isEnabled()) {
if (e->type() == QEvent::KeyPress) {
t->keysymPressed(sym);
} else if (e->type() == QEvent::KeyRelease) {
t->keysymReleased(sym);
}
}
}
}
return true;
}
}
return false;
}
QWindow *VirtualKeyboard::inputPanel() const
{
return m_inputWindow.data();
}
} }

View file

@ -33,16 +33,13 @@ public:
void init(); void init();
bool event(QEvent *e) override; bool event(QEvent *e) override;
bool eventFilter(QObject *o, QEvent *event) override; void hide();
void show();
QWindow *inputPanel() const;
Q_SIGNALS: Q_SIGNALS:
void enabledChanged(bool enabled); void enabledChanged(bool enabled);
private: private:
void show();
void hide();
void setEnabled(bool enable); void setEnabled(bool enable);
void updateSni(); void updateSni();
void updateInputPanelState(); void updateInputPanelState();
@ -50,7 +47,6 @@ private:
bool m_enabled = false; bool m_enabled = false;
KStatusNotifierItem *m_sni = nullptr; KStatusNotifierItem *m_sni = nullptr;
QScopedPointer<QQuickView> m_inputWindow;
QPointer<AbstractClient> m_inputClient; QPointer<AbstractClient> m_inputClient;
QPointer<AbstractClient> m_trackedClient; QPointer<AbstractClient> m_trackedClient;
// If a surface loses focus immediately after being resized by the keyboard, don't react to it to avoid resize loops // If a surface loses focus immediately after being resized by the keyboard, don't react to it to avoid resize loops