[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:
parent
18397c1028
commit
981b312323
7 changed files with 53 additions and 6 deletions
|
@ -91,6 +91,7 @@ private:
|
||||||
HelperWindow::HelperWindow()
|
HelperWindow::HelperWindow()
|
||||||
: QRasterWindow(nullptr)
|
: QRasterWindow(nullptr)
|
||||||
{
|
{
|
||||||
|
setFlags(Qt::FramelessWindowHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
HelperWindow::~HelperWindow() = default;
|
HelperWindow::~HelperWindow() = default;
|
||||||
|
|
|
@ -430,6 +430,13 @@ class InternalWindowEventFilter : public InputEventFilter {
|
||||||
if (!internal) {
|
if (!internal) {
|
||||||
return false;
|
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(),
|
QMouseEvent e(event->type(),
|
||||||
event->pos() - internal->position(),
|
event->pos() - internal->position(),
|
||||||
event->globalPos(),
|
event->globalPos(),
|
||||||
|
@ -1534,7 +1541,7 @@ void InputDeviceHandler::updateInternalWindow(const QPointF &pos)
|
||||||
if (!w->isVisible()) {
|
if (!w->isVisible()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (w->geometry().contains(pos.toPoint())) {
|
if ((*it)->geometry().contains(pos.toPoint())) {
|
||||||
// check input mask
|
// check input mask
|
||||||
const QRegion mask = w->mask().translated(w->geometry().topLeft());
|
const QRegion mask = w->mask().translated(w->geometry().topLeft());
|
||||||
if (!mask.isEmpty() && !mask.contains(pos.toPoint())) {
|
if (!mask.isEmpty() && !mask.contains(pos.toPoint())) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
#include <QOpenGLFramebufferObject>
|
#include <QOpenGLFramebufferObject>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <KWayland/Client/buffer.h>
|
#include <KWayland/Client/buffer.h>
|
||||||
#include <KWayland/Client/connection_thread.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);
|
wl_egl_window_resize(m_eglWaylandWindow, geometry().width(), geometry().height(), 0, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
QWindowSystemInterface::handleGeometryChange(window(), geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::unmap()
|
void Window::unmap()
|
||||||
|
|
|
@ -367,11 +367,14 @@ void PointerInputRedirection::update()
|
||||||
if (!m_internalWindow) {
|
if (!m_internalWindow) {
|
||||||
updateDecoration(t, m_pos);
|
updateDecoration(t, m_pos);
|
||||||
} else {
|
} else {
|
||||||
// TODO: send hover leave to decoration
|
updateDecoration(waylandServer()->findClient(m_internalWindow), m_pos);
|
||||||
if (m_decoration) {
|
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) {
|
if (m_decoration || m_internalWindow) {
|
||||||
t = nullptr;
|
t = nullptr;
|
||||||
|
|
|
@ -178,6 +178,7 @@ void ShellClient::init()
|
||||||
if (m_internalWindow) {
|
if (m_internalWindow) {
|
||||||
updateInternalWindowGeometry();
|
updateInternalWindowGeometry();
|
||||||
setOnAllDesktops(true);
|
setOnAllDesktops(true);
|
||||||
|
updateDecoration(true);
|
||||||
} else {
|
} else {
|
||||||
doSetGeometry(QRect(QPoint(0, 0), m_clientSize));
|
doSetGeometry(QRect(QPoint(0, 0), m_clientSize));
|
||||||
setDesktop(VirtualDesktopManager::self()->current());
|
setDesktop(VirtualDesktopManager::self()->current());
|
||||||
|
@ -484,6 +485,13 @@ void ShellClient::doSetGeometry(const QRect &rect)
|
||||||
if (!m_unmapped) {
|
if (!m_unmapped) {
|
||||||
addWorkspaceRepaint(visibleRect());
|
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();
|
triggerDecorationRepaint();
|
||||||
if (hasStrut()) {
|
if (hasStrut()) {
|
||||||
workspace()->updateClientArea();
|
workspace()->updateClientArea();
|
||||||
|
@ -526,6 +534,9 @@ void ShellClient::closeWindow()
|
||||||
if (m_qtExtendedSurface && isCloseable()) {
|
if (m_qtExtendedSurface && isCloseable()) {
|
||||||
m_qtExtendedSurface->close();
|
m_qtExtendedSurface->close();
|
||||||
}
|
}
|
||||||
|
if (m_internalWindow) {
|
||||||
|
m_internalWindow->hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractClient *ShellClient::findModal(bool allow_itself)
|
AbstractClient *ShellClient::findModal(bool allow_itself)
|
||||||
|
@ -542,6 +553,9 @@ bool ShellClient::isCloseable() const
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (m_internal) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return m_qtExtendedSurface ? true : false;
|
return m_qtExtendedSurface ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +571,9 @@ bool ShellClient::isFullScreen() const
|
||||||
|
|
||||||
bool ShellClient::isMaximizable() const
|
bool ShellClient::isMaximizable() const
|
||||||
{
|
{
|
||||||
|
if (m_internal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,7 +711,7 @@ MaximizeMode ShellClient::maximizeMode() const
|
||||||
bool ShellClient::noBorder() const
|
bool ShellClient::noBorder() const
|
||||||
{
|
{
|
||||||
if (isInternal()) {
|
if (isInternal()) {
|
||||||
return true;
|
return m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
|
||||||
}
|
}
|
||||||
if (m_serverDecoration) {
|
if (m_serverDecoration) {
|
||||||
if (m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
|
if (m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
|
||||||
|
@ -791,6 +808,9 @@ bool ShellClient::userCanSetNoBorder() const
|
||||||
if (m_serverDecoration && m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
|
if (m_serverDecoration && m_serverDecoration->mode() == ServerSideDecorationManagerInterface::Mode::Server) {
|
||||||
return !isFullScreen() && !isShade() && !tabGroup();
|
return !isFullScreen() && !isShade() && !tabGroup();
|
||||||
}
|
}
|
||||||
|
if (m_internal) {
|
||||||
|
return !m_internalWindowFlags.testFlag(Qt::FramelessWindowHint) || m_internalWindowFlags.testFlag(Qt::Popup);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,6 +872,7 @@ void ShellClient::findInternalWindow()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_internalWindow = w;
|
m_internalWindow = w;
|
||||||
|
m_internalWindowFlags = m_internalWindow->flags();
|
||||||
connect(m_internalWindow, &QWindow::xChanged, this, &ShellClient::updateInternalWindowGeometry);
|
connect(m_internalWindow, &QWindow::xChanged, this, &ShellClient::updateInternalWindowGeometry);
|
||||||
connect(m_internalWindow, &QWindow::yChanged, this, &ShellClient::updateInternalWindowGeometry);
|
connect(m_internalWindow, &QWindow::yChanged, this, &ShellClient::updateInternalWindowGeometry);
|
||||||
connect(m_internalWindow, &QWindow::destroyed, this, [this] { m_internalWindow = nullptr; });
|
connect(m_internalWindow, &QWindow::destroyed, this, [this] { m_internalWindow = nullptr; });
|
||||||
|
@ -871,7 +892,8 @@ void ShellClient::updateInternalWindowGeometry()
|
||||||
if (!m_internalWindow) {
|
if (!m_internalWindow) {
|
||||||
return;
|
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
|
bool ShellClient::isInternal() const
|
||||||
|
@ -907,6 +929,9 @@ void ShellClient::requestGeometry(const QRect &rect)
|
||||||
m_xdgShellSurface->configure(xdgSurfaceStates(), size);
|
m_xdgShellSurface->configure(xdgSurfaceStates(), size);
|
||||||
}
|
}
|
||||||
m_blockedRequestGeometry = QRect();
|
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)
|
void ShellClient::clientFullScreenChanged(bool fullScreen)
|
||||||
|
@ -950,6 +975,9 @@ void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force)
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h));
|
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()
|
void ShellClient::unmap()
|
||||||
|
|
|
@ -170,6 +170,7 @@ private:
|
||||||
bool m_closing = false;
|
bool m_closing = false;
|
||||||
quint32 m_windowId = 0;
|
quint32 m_windowId = 0;
|
||||||
QWindow *m_internalWindow = nullptr;
|
QWindow *m_internalWindow = nullptr;
|
||||||
|
Qt::WindowFlags m_internalWindowFlags = Qt::WindowFlags();
|
||||||
bool m_unmapped = true;
|
bool m_unmapped = true;
|
||||||
MaximizeMode m_maximizeMode = MaximizeRestore;
|
MaximizeMode m_maximizeMode = MaximizeRestore;
|
||||||
QRect m_geomMaximizeRestore; // size and position of the window before it was set to maximize
|
QRect m_geomMaximizeRestore; // size and position of the window before it was set to maximize
|
||||||
|
|
|
@ -1640,6 +1640,11 @@ AbstractClient *Workspace::findAbstractClient(std::function<bool (const Abstract
|
||||||
if (Client *ret = Toplevel::findInList(desktops, func)) {
|
if (Client *ret = Toplevel::findInList(desktops, func)) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (waylandServer()) {
|
||||||
|
if (AbstractClient *ret = Toplevel::findInList(waylandServer()->internalClients(), func)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue