[Wayland] Make it possible to have internal windows decorated

Summary:
With this change KWin can create window decorations for internal windows.
Thus it's also possible to move internal windows and resize them which is
especially important for the debug console.

Reviewers: #kwin, #plasma_on_wayland, sebas

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D2371
This commit is contained in:
Martin Gräßlin 2016-05-09 14:48:10 +02:00
parent 18397c1028
commit 981b312323
7 changed files with 53 additions and 6 deletions

View file

@ -91,6 +91,7 @@ private:
HelperWindow::HelperWindow()
: QRasterWindow(nullptr)
{
setFlags(Qt::FramelessWindowHint);
}
HelperWindow::~HelperWindow() = default;

View file

@ -430,6 +430,13 @@ class InternalWindowEventFilter : public InputEventFilter {
if (!internal) {
return false;
}
if (event->buttons() == Qt::NoButton) {
// update pointer window only if no button is pressed
input()->pointer()->update();
}
if (!internal) {
return false;
}
QMouseEvent e(event->type(),
event->pos() - internal->position(),
event->globalPos(),
@ -1534,7 +1541,7 @@ void InputDeviceHandler::updateInternalWindow(const QPointF &pos)
if (!w->isVisible()) {
continue;
}
if (w->geometry().contains(pos.toPoint())) {
if ((*it)->geometry().contains(pos.toPoint())) {
// check input mask
const QRegion mask = w->mask().translated(w->geometry().topLeft());
if (!mask.isEmpty() && !mask.contains(pos.toPoint())) {

View file

@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <logging.h>
#include <QOpenGLFramebufferObject>
#include <qpa/qwindowsysteminterface.h>
#include <KWayland/Client/buffer.h>
#include <KWayland/Client/connection_thread.h>
@ -103,6 +104,7 @@ void Window::setGeometry(const QRect &rect)
wl_egl_window_resize(m_eglWaylandWindow, geometry().width(), geometry().height(), 0, 0);
}
#endif
QWindowSystemInterface::handleGeometryChange(window(), geometry());
}
void Window::unmap()

View file

@ -367,11 +367,14 @@ void PointerInputRedirection::update()
if (!m_internalWindow) {
updateDecoration(t, m_pos);
} else {
// TODO: send hover leave to decoration
updateDecoration(waylandServer()->findClient(m_internalWindow), m_pos);
if (m_decoration) {
m_decoration->client()->leaveEvent();
disconnect(m_internalWindowConnection);
m_internalWindowConnection = QMetaObject::Connection();
QEvent event(QEvent::Leave);
QCoreApplication::sendEvent(m_internalWindow.data(), &event);
m_internalWindow.clear();
}
m_decoration.clear();
}
if (m_decoration || m_internalWindow) {
t = nullptr;

View file

@ -178,6 +178,7 @@ void ShellClient::init()
if (m_internalWindow) {
updateInternalWindowGeometry();
setOnAllDesktops(true);
updateDecoration(true);
} else {
doSetGeometry(QRect(QPoint(0, 0), m_clientSize));
setDesktop(VirtualDesktopManager::self()->current());
@ -484,6 +485,13 @@ void ShellClient::doSetGeometry(const QRect &rect)
if (!m_unmapped) {
addWorkspaceRepaint(visibleRect());
}
if (m_internalWindow) {
const QRect windowRect = QRect(geom.topLeft() + QPoint(borderLeft(), borderTop()),
geom.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()));
if (m_internalWindow->geometry() != windowRect) {
m_internalWindow->setGeometry(windowRect);
}
}
triggerDecorationRepaint();
if (hasStrut()) {
workspace()->updateClientArea();
@ -526,6 +534,9 @@ void ShellClient::closeWindow()
if (m_qtExtendedSurface && isCloseable()) {
m_qtExtendedSurface->close();
}
if (m_internalWindow) {
m_internalWindow->hide();
}
}
AbstractClient *ShellClient::findModal(bool allow_itself)
@ -542,6 +553,9 @@ bool ShellClient::isCloseable() const
if (m_xdgShellSurface) {
return true;
}
if (m_internal) {
return true;
}
return m_qtExtendedSurface ? true : false;
}
@ -557,6 +571,9 @@ bool ShellClient::isFullScreen() const
bool ShellClient::isMaximizable() const
{
if (m_internal) {
return false;
}
return true;
}
@ -694,7 +711,7 @@ MaximizeMode ShellClient::maximizeMode() const
bool ShellClient::noBorder() const
{
if (isInternal()) {
return true;
return m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
}
if (m_serverDecoration) {
if (m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
@ -791,6 +808,9 @@ bool ShellClient::userCanSetNoBorder() const
if (m_serverDecoration && m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
return !isFullScreen() && !isShade() && !tabGroup();
}
if (m_internal) {
return !m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
}
return false;
}
@ -852,6 +872,7 @@ void ShellClient::findInternalWindow()
continue;
}
m_internalWindow = w;
m_internalWindowFlags = m_internalWindow->flags();
connect(m_internalWindow, &QWindow::xChanged, this, &ShellClient::updateInternalWindowGeometry);
connect(m_internalWindow, &QWindow::yChanged, this, &ShellClient::updateInternalWindowGeometry);
connect(m_internalWindow, &QWindow::destroyed, this, [this] { m_internalWindow = nullptr; });
@ -871,7 +892,8 @@ void ShellClient::updateInternalWindowGeometry()
if (!m_internalWindow) {
return;
}
doSetGeometry(m_internalWindow->geometry());
doSetGeometry(QRect(m_internalWindow->geometry().topLeft() - QPoint(borderLeft(), borderTop()),
m_internalWindow->geometry().size() + QSize(borderLeft() + borderRight(), borderTop() + borderBottom())));
}
bool ShellClient::isInternal() const
@ -907,6 +929,9 @@ void ShellClient::requestGeometry(const QRect &rect)
m_xdgShellSurface->configure(xdgSurfaceStates(), size);
}
m_blockedRequestGeometry = QRect();
if (m_internal) {
m_internalWindow->setGeometry(QRect(rect.topLeft() + QPoint(borderLeft(), borderTop()), rect.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom())));
}
}
void ShellClient::clientFullScreenChanged(bool fullScreen)
@ -950,6 +975,9 @@ void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force)
if (m_xdgShellSurface) {
m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h));
}
if (m_internal) {
m_internalWindow->setGeometry(QRect(pos() + QPoint(borderLeft(), borderTop()), QSize(w, h) - QSize(borderLeft() + borderRight(), borderTop() + borderBottom())));
}
}
void ShellClient::unmap()

View file

@ -170,6 +170,7 @@ private:
bool m_closing = false;
quint32 m_windowId = 0;
QWindow *m_internalWindow = nullptr;
Qt::WindowFlags m_internalWindowFlags = Qt::WindowFlags();
bool m_unmapped = true;
MaximizeMode m_maximizeMode = MaximizeRestore;
QRect m_geomMaximizeRestore; // size and position of the window before it was set to maximize

View file

@ -1640,6 +1640,11 @@ AbstractClient *Workspace::findAbstractClient(std::function<bool (const Abstract
if (Client *ret = Toplevel::findInList(desktops, func)) {
return ret;
}
if (waylandServer()) {
if (AbstractClient *ret = Toplevel::findInList(waylandServer()->internalClients(), func)) {
return ret;
}
}
return nullptr;
}