File indexing completed on 2024-11-10 04:56:35

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
0006     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     Since the functionality provided in this class has been moved from
0009     class Workspace, it is not clear who exactly has written the code.
0010     The list below contains the copyright holders of the class Workspace.
0011 
0012     SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
0013     SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
0014     SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
0015 
0016     SPDX-License-Identifier: GPL-2.0-or-later
0017 */
0018 #include "x11_standalone_edge.h"
0019 #include "atoms.h"
0020 #include "cursor.h"
0021 
0022 namespace KWin
0023 {
0024 
0025 WindowBasedEdge::WindowBasedEdge(ScreenEdges *parent)
0026     : Edge(parent)
0027     , m_window(XCB_WINDOW_NONE)
0028     , m_approachWindow(XCB_WINDOW_NONE)
0029 {
0030 }
0031 
0032 WindowBasedEdge::~WindowBasedEdge()
0033 {
0034 }
0035 
0036 void WindowBasedEdge::doActivate()
0037 {
0038     createWindow();
0039     createApproachWindow();
0040     doUpdateBlocking();
0041 }
0042 
0043 void WindowBasedEdge::doDeactivate()
0044 {
0045     m_window.reset();
0046     m_approachWindow.reset();
0047 }
0048 
0049 void WindowBasedEdge::createWindow()
0050 {
0051     if (m_window.isValid()) {
0052         return;
0053     }
0054     const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
0055     const uint32_t values[] = {
0056         true,
0057         XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION};
0058     m_window.create(geometry(), XCB_WINDOW_CLASS_INPUT_ONLY, mask, values);
0059     m_window.map();
0060     // Set XdndAware on the windows, so that DND enter events are received (#86998)
0061     xcb_atom_t version = 4; // XDND version
0062     xcb_change_property(connection(), XCB_PROP_MODE_REPLACE, m_window,
0063                         atoms->xdnd_aware, XCB_ATOM_ATOM, 32, 1, (unsigned char *)(&version));
0064 }
0065 
0066 void WindowBasedEdge::createApproachWindow()
0067 {
0068     if (!activatesForPointer()) {
0069         return;
0070     }
0071     if (m_approachWindow.isValid()) {
0072         return;
0073     }
0074     if (!approachGeometry().isValid()) {
0075         return;
0076     }
0077     const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
0078     const uint32_t values[] = {
0079         true,
0080         XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION};
0081     m_approachWindow.create(approachGeometry(), XCB_WINDOW_CLASS_INPUT_ONLY, mask, values);
0082     m_approachWindow.map();
0083 }
0084 
0085 void WindowBasedEdge::doGeometryUpdate()
0086 {
0087     m_window.setGeometry(geometry());
0088     if (m_approachWindow.isValid()) {
0089         m_approachWindow.setGeometry(approachGeometry());
0090     }
0091 }
0092 
0093 void WindowBasedEdge::doStartApproaching()
0094 {
0095     if (!activatesForPointer()) {
0096         return;
0097     }
0098     m_approachWindow.unmap();
0099     Cursor *cursor = Cursors::self()->mouse();
0100     m_cursorPollingConnection = connect(cursor, &Cursor::posChanged, this, &WindowBasedEdge::updateApproaching);
0101     cursor->startMousePolling();
0102 }
0103 
0104 void WindowBasedEdge::doStopApproaching()
0105 {
0106     if (!m_cursorPollingConnection) {
0107         return;
0108     }
0109     disconnect(m_cursorPollingConnection);
0110     m_cursorPollingConnection = QMetaObject::Connection();
0111     Cursors::self()->mouse()->stopMousePolling();
0112     m_approachWindow.map();
0113 }
0114 
0115 void WindowBasedEdge::doUpdateBlocking()
0116 {
0117     if (!isReserved()) {
0118         return;
0119     }
0120     if (isBlocked()) {
0121         m_window.unmap();
0122         m_approachWindow.unmap();
0123     } else {
0124         m_window.map();
0125         m_approachWindow.map();
0126     }
0127 }
0128 
0129 }
0130 
0131 #include "moc_x11_standalone_edge.cpp"