File indexing completed on 2024-04-28 16:49:16

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_interface.h"
0010 #include "wayland_server.h"
0011 #include "workspace.h"
0012 #include "xdgshellwindow.h"
0013 
0014 using namespace KWaylandServer;
0015 
0016 namespace KWin
0017 {
0018 
0019 /**
0020  * The WaylandXdgShellIntegration class is a factory class for xdg-shell windows.
0021  *
0022  * The xdg-shell protocol defines two surface roles - xdg_toplevel and xdg_popup. On the
0023  * compositor side, those roles are represented by XdgToplevelWindow and XdgPopupWindow,
0024  * respectively.
0025  *
0026  * WaylandXdgShellIntegration monitors for new xdg_toplevel and xdg_popup objects. If it
0027  * detects one, it will create an XdgToplevelWindow or XdgPopupWindow based on the current
0028  * surface role of the underlying xdg_surface object.
0029  */
0030 
0031 XdgShellIntegration::XdgShellIntegration(QObject *parent)
0032     : WaylandShellIntegration(parent)
0033 {
0034     XdgShellInterface *shell = new XdgShellInterface(waylandServer()->display(), this);
0035 
0036     connect(shell, &XdgShellInterface::toplevelCreated,
0037             this, &XdgShellIntegration::registerXdgToplevel);
0038     connect(shell, &XdgShellInterface::popupCreated,
0039             this, &XdgShellIntegration::registerXdgPopup);
0040 }
0041 
0042 void XdgShellIntegration::registerXdgToplevel(XdgToplevelInterface *toplevel)
0043 {
0044     // Note that the window is going to be destroyed and immediately re-created when the
0045     // underlying surface is unmapped. XdgToplevelWindow is re-created right away since
0046     // we don't want too loose any window requests that are allowed to be sent prior to
0047     // the first initial commit, e.g. set_maximized or set_fullscreen.
0048     connect(toplevel, &XdgToplevelInterface::resetOccurred,
0049             this, [this, toplevel] {
0050                 createXdgToplevelWindow(toplevel);
0051             });
0052 
0053     createXdgToplevelWindow(toplevel);
0054 }
0055 
0056 void XdgShellIntegration::createXdgToplevelWindow(XdgToplevelInterface *toplevel)
0057 {
0058     if (!workspace()) {
0059         qCWarning(KWIN_CORE, "An xdg-toplevel surface has been created while the compositor "
0060                              "is still not fully initialized. That is a compositor bug!");
0061         return;
0062     }
0063 
0064     Q_EMIT windowCreated(new XdgToplevelWindow(toplevel));
0065 }
0066 
0067 void XdgShellIntegration::registerXdgPopup(XdgPopupInterface *popup)
0068 {
0069     if (!workspace()) {
0070         qCWarning(KWIN_CORE, "An xdg-popup surface has been created while the compositor is "
0071                              "still not fully initialized. That is a compositor bug!");
0072         return;
0073     }
0074 
0075     Q_EMIT windowCreated(new XdgPopupWindow(popup));
0076 }
0077 
0078 } // namespace KWin