Remove embedded implementation of the Virtual Keyboard
This commit is contained in:
parent
7aabd45df9
commit
3733e3e77f
8 changed files with 35 additions and 213 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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})
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue