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"