kwin/src/inputpanelv1window.cpp
Vlad Zahorodnii 7fffe99328 build: Add -Wno-unused-parameter compiler option
Due to being a compositor, kwin has to conform to some certain
interfaces. It means a lot of virtual functions and function tables to
integrate with C APIs. Naturally, we not always want to use every
argument in such functions.

Since we get -Wunused-parameter from -Wall, we have to plumb those
unused arguments in order to suppress compiler warnings at the moment.

However, I don't think that extra work is worth it. We cannot change or
alter prototypes in any way to fix the warning the desired way. Q_UNUSED
and similar macros are not good indicators of whether an argument is
used too, we tend to overlook putting or removing those macros. I've
also noticed that Q_UNUSED are not used to guide us with the removal no
longer needed parameters.

Therefore, I think it's worth adding -Wno-unused-parameter compiler
option to stop the compiler producing warnings about unused parameters.
It changes nothing except that we don't need to put Q_UNUSED anymore,
which can be really cumbersome sometimes. Note that it doesn't affect
unused variables, you'll still get a -Wunused-variable compiler warning
if a variable is unused.
2022-10-31 15:50:37 +00:00

212 lines
6.7 KiB
C++

/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "inputpanelv1window.h"
#include "core/output.h"
#include "deleted.h"
#include "inputmethod.h"
#include "wayland/output_interface.h"
#include "wayland/seat_interface.h"
#include "wayland/surface_interface.h"
#include "wayland/textinput_v2_interface.h"
#include "wayland/textinput_v3_interface.h"
#include "wayland_server.h"
#include "workspace.h"
using namespace KWaylandServer;
namespace KWin
{
InputPanelV1Window::InputPanelV1Window(InputPanelSurfaceV1Interface *panelSurface)
: WaylandWindow(panelSurface->surface())
, m_panelSurface(panelSurface)
{
setSkipSwitcher(true);
setSkipPager(true);
setSkipTaskbar(true);
connect(surface(), &SurfaceInterface::aboutToBeDestroyed, this, &InputPanelV1Window::destroyWindow);
connect(surface(), &SurfaceInterface::sizeChanged, this, &InputPanelV1Window::reposition);
connect(surface(), &SurfaceInterface::mapped, this, &InputPanelV1Window::handleMapped);
connect(panelSurface, &InputPanelSurfaceV1Interface::topLevel, this, &InputPanelV1Window::showTopLevel);
connect(panelSurface, &InputPanelSurfaceV1Interface::overlayPanel, this, &InputPanelV1Window::showOverlayPanel);
connect(panelSurface, &InputPanelSurfaceV1Interface::destroyed, this, &InputPanelV1Window::destroyWindow);
kwinApp()->inputMethod()->setPanel(this);
}
void InputPanelV1Window::showOverlayPanel()
{
setOutput(nullptr);
m_mode = Mode::Overlay;
maybeShow();
}
void InputPanelV1Window::showTopLevel(OutputInterface *output, InputPanelSurfaceV1Interface::Position position)
{
m_mode = Mode::VirtualKeyboard;
setOutput(output);
maybeShow();
}
void InputPanelV1Window::allow()
{
m_allowed = true;
maybeShow();
}
void InputPanelV1Window::show()
{
m_virtualKeyboardShouldBeShown = true;
maybeShow();
}
void InputPanelV1Window::hide()
{
m_virtualKeyboardShouldBeShown = false;
if (readyForPainting() && m_mode != Mode::Overlay) {
hideClient();
}
}
void KWin::InputPanelV1Window::reposition()
{
if (!readyForPainting()) {
return;
}
switch (m_mode) {
case Mode::None: {
// should never happen
}; break;
case Mode::VirtualKeyboard: {
QSizeF panelSize = surface()->size();
if (!panelSize.isValid() || panelSize.isEmpty()) {
return;
}
QRectF availableArea;
QRectF outputArea;
if (m_output) {
outputArea = m_output->geometry();
if (waylandServer()->isScreenLocked()) {
availableArea = outputArea;
} else {
availableArea = workspace()->clientArea(MaximizeArea, this, m_output);
}
} else {
availableArea = workspace()->clientArea(MaximizeArea, this);
outputArea = workspace()->clientArea(FullScreenArea, this);
}
panelSize = panelSize.boundedTo(availableArea.size());
QRectF geo(QPointF(availableArea.left(), availableArea.top() + availableArea.height() - panelSize.height()), panelSize);
geo.translate((availableArea.width() - panelSize.width()) / 2, availableArea.height() - outputArea.height());
moveResize(geo);
} break;
case Mode::Overlay: {
auto textInputSurface = waylandServer()->seat()->focusedTextInputSurface();
auto textWindow = waylandServer()->findWindow(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 (textWindow) {
cursorRectangle.translate(textWindow->bufferGeometry().topLeft().toPoint());
const QRectF screen = Workspace::self()->clientArea(PlacementArea, this, cursorRectangle.bottomLeft());
// Reuse the similar logic like xdg popup
QRectF popupRect(popupOffset(cursorRectangle, Qt::BottomEdge | 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 =
QRectF(popupOffset(cursorRectangle, Qt::TopEdge | 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;
}
}
void InputPanelV1Window::destroyWindow()
{
markAsZombie();
Deleted *deleted = Deleted::create(this);
Q_EMIT windowClosed(this, deleted);
StackingUpdatesBlocker blocker(workspace());
waylandServer()->removeWindow(this);
deleted->unrefWindow();
delete this;
}
NET::WindowType InputPanelV1Window::windowType(bool, int) const
{
return NET::Utility;
}
QRectF InputPanelV1Window::inputGeometry() const
{
return readyForPainting() ? QRectF(surface()->input().boundingRect()).translated(pos()) : QRectF();
}
void InputPanelV1Window::setOutput(OutputInterface *outputIface)
{
if (m_output) {
disconnect(m_output, &Output::geometryChanged, this, &InputPanelV1Window::reposition);
}
m_output = outputIface ? outputIface->handle() : nullptr;
if (m_output) {
connect(m_output, &Output::geometryChanged, this, &InputPanelV1Window::reposition);
}
}
void InputPanelV1Window::moveResizeInternal(const QRectF &rect, MoveResizeMode mode)
{
updateGeometry(rect);
}
void InputPanelV1Window::handleMapped()
{
updateDepth();
maybeShow();
}
void InputPanelV1Window::maybeShow()
{
const bool shouldShow = m_mode == Mode::Overlay || (m_mode == Mode::VirtualKeyboard && m_allowed && m_virtualKeyboardShouldBeShown);
if (shouldShow && !isZombie() && surface()->isMapped()) {
setReadyForPainting();
reposition();
showClient();
}
}
} // namespace KWin