File indexing completed on 2024-11-10 04:58:06

0001 /*
0002     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "xdgshellintegration.h"
0008 #include "wayland/display.h"
0009 #include "wayland/xdgshell.h"
0010 #include "wayland_server.h"
0011 #include "workspace.h"
0012 #include "xdgshellwindow.h"
0013 
0014 namespace KWin
0015 {
0016 
0017 /**
0018  * The WaylandXdgShellIntegration class is a factory class for xdg-shell windows.
0019  *
0020  * The xdg-shell protocol defines two surface roles - xdg_toplevel and xdg_popup. On the
0021  * compositor side, those roles are represented by XdgToplevelWindow and XdgPopupWindow,
0022  * respectively.
0023  *
0024  * WaylandXdgShellIntegration monitors for new xdg_toplevel and xdg_popup objects. If it
0025  * detects one, it will create an XdgToplevelWindow or XdgPopupWindow based on the current
0026  * surface role of the underlying xdg_surface object.
0027  */
0028 
0029 XdgShellIntegration::XdgShellIntegration(QObject *parent)
0030     : WaylandShellIntegration(parent)
0031     , m_shell(new XdgShellInterface(waylandServer()->display(), this))
0032 {
0033     connect(m_shell, &XdgShellInterface::toplevelCreated,
0034             this, &XdgShellIntegration::registerXdgToplevel);
0035     connect(m_shell, &XdgShellInterface::popupCreated,
0036             this, &XdgShellIntegration::registerXdgPopup);
0037 }
0038 
0039 std::chrono::milliseconds XdgShellIntegration::pingTimeout() const
0040 {
0041     return m_shell->pingTimeoutInterval();
0042 }
0043 
0044 void XdgShellIntegration::setPingTimeout(std::chrono::milliseconds pingTimeout)
0045 {
0046     m_shell->setPingTimeoutInterval(pingTimeout);
0047 }
0048 
0049 void XdgShellIntegration::registerXdgToplevel(XdgToplevelInterface *toplevel)
0050 {
0051     // Note that the window is going to be destroyed and immediately re-created when the
0052     // underlying surface is unmapped. XdgToplevelWindow is re-created right away since
0053     // we don't want too loose any window requests that are allowed to be sent prior to
0054     // the first initial commit, e.g. set_maximized or set_fullscreen.
0055     connect(toplevel, &XdgToplevelInterface::resetOccurred,
0056             this, [this, toplevel] {
0057                 createXdgToplevelWindow(toplevel);
0058             });
0059 
0060     createXdgToplevelWindow(toplevel);
0061 }
0062 
0063 void XdgShellIntegration::createXdgToplevelWindow(XdgToplevelInterface *toplevel)
0064 {
0065     if (!workspace()) {
0066         qCWarning(KWIN_CORE, "An xdg-toplevel surface has been created while the compositor "
0067                              "is still not fully initialized. That is a compositor bug!");
0068         return;
0069     }
0070 
0071     Q_EMIT windowCreated(new XdgToplevelWindow(toplevel));
0072 }
0073 
0074 void XdgShellIntegration::registerXdgPopup(XdgPopupInterface *popup)
0075 {
0076     if (!workspace()) {
0077         qCWarning(KWIN_CORE, "An xdg-popup surface has been created while the compositor is "
0078                              "still not fully initialized. That is a compositor bug!");
0079         return;
0080     }
0081 
0082     Q_EMIT windowCreated(new XdgPopupWindow(popup));
0083 }
0084 
0085 } // namespace KWin
0086 
0087 #include "moc_xdgshellintegration.cpp"