KWin
Loading...
Searching...
No Matches
common.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11/*
12
13 This file is for (very) small utility functions/classes.
14
15*/
16
17#include "utils/common.h"
18#include "effect/xcb.h"
19#include "utils/c_ptr.h"
20
21#include <QPainter>
22#include <QWidget>
23#include <kkeyserver.h>
24
25#ifndef KCMRULES
26#include <QApplication>
27#include <QDebug>
28#endif
29
30Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core", QtWarningMsg)
31Q_LOGGING_CATEGORY(KWIN_OPENGL, "kwin_scene_opengl", QtWarningMsg)
32Q_LOGGING_CATEGORY(KWIN_QPAINTER, "kwin_scene_qpainter", QtWarningMsg)
33Q_LOGGING_CATEGORY(KWIN_VIRTUALKEYBOARD, "kwin_virtualkeyboard", QtWarningMsg)
34namespace KWin
35{
36
37#ifndef KCMRULES
38
39//************************************
40// StrutRect
41//************************************
42
44 : QRect(rect)
45 , m_area(area)
46{
47}
48
49StrutRect::StrutRect(int x, int y, int width, int height, StrutArea area)
50 : QRect(x, y, width, height)
51 , m_area(area)
52{
53}
54
56 : QRect(other)
57 , m_area(other.area())
58{
59}
60
62{
63 if (this != &other) {
64 QRect::operator=(other);
65 m_area = other.area();
66 }
67 return *this;
68}
69
70static int server_grab_count = 0;
71
73{
74 if (++server_grab_count == 1) {
75 xcb_grab_server(connection());
76 }
77}
78
80{
81 Q_ASSERT(server_grab_count > 0);
82 if (--server_grab_count == 0) {
83 xcb_ungrab_server(connection());
84 xcb_flush(connection());
85 }
86}
87
88static bool keyboard_grabbed = false;
89
90bool grabXKeyboard(xcb_window_t w)
91{
92 if (QWidget::keyboardGrabber() != nullptr) {
93 return false;
94 }
95 if (keyboard_grabbed) {
96 qCDebug(KWIN_CORE) << "Failed to grab X Keyboard: already grabbed by us";
97 return false;
98 }
99 if (qApp->activePopupWidget() != nullptr) {
100 qCDebug(KWIN_CORE) << "Failed to grab X Keyboard: no popup widget";
101 return false;
102 }
103 if (w == XCB_WINDOW_NONE) {
104 w = rootWindow();
105 }
106 const xcb_grab_keyboard_cookie_t c = xcb_grab_keyboard_unchecked(connection(), false, w, xTime(),
107 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
108 UniqueCPtr<xcb_grab_keyboard_reply_t> grab(xcb_grab_keyboard_reply(connection(), c, nullptr));
109 if (!grab) {
110 qCDebug(KWIN_CORE) << "Failed to grab X Keyboard: grab null";
111 return false;
112 }
113 if (grab->status != XCB_GRAB_STATUS_SUCCESS) {
114 qCDebug(KWIN_CORE) << "Failed to grab X Keyboard: grab failed with status" << grab->status;
115 return false;
116 }
117 keyboard_grabbed = true;
118 return true;
119}
120
122{
123 if (!keyboard_grabbed) {
124 // grabXKeyboard() may fail sometimes, so don't fail, but at least warn anyway
125 qCDebug(KWIN_CORE) << "ungrabXKeyboard() called but keyboard not grabbed!";
126 }
127 keyboard_grabbed = false;
128 xcb_ungrab_keyboard(connection(), XCB_TIME_CURRENT_TIME);
129}
130
131#endif
132
133// converting between X11 mouse/keyboard state mask and Qt button/keyboard states
134
135Qt::MouseButton x11ToQtMouseButton(int button)
136{
137 if (button == XCB_BUTTON_INDEX_1) {
138 return Qt::LeftButton;
139 }
140 if (button == XCB_BUTTON_INDEX_2) {
141 return Qt::MiddleButton;
142 }
143 if (button == XCB_BUTTON_INDEX_3) {
144 return Qt::RightButton;
145 }
146 if (button == XCB_BUTTON_INDEX_4) {
147 return Qt::XButton1;
148 }
149 if (button == XCB_BUTTON_INDEX_5) {
150 return Qt::XButton2;
151 }
152 return Qt::NoButton;
153}
154
155Qt::MouseButtons x11ToQtMouseButtons(int state)
156{
157 Qt::MouseButtons ret = {};
158 if (state & XCB_KEY_BUT_MASK_BUTTON_1) {
159 ret |= Qt::LeftButton;
160 }
161 if (state & XCB_KEY_BUT_MASK_BUTTON_2) {
162 ret |= Qt::MiddleButton;
163 }
164 if (state & XCB_KEY_BUT_MASK_BUTTON_3) {
165 ret |= Qt::RightButton;
166 }
167 if (state & XCB_KEY_BUT_MASK_BUTTON_4) {
168 ret |= Qt::XButton1;
169 }
170 if (state & XCB_KEY_BUT_MASK_BUTTON_5) {
171 ret |= Qt::XButton2;
172 }
173 return ret;
174}
175
176Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
177{
178 Qt::KeyboardModifiers ret = {};
179 if (state & XCB_KEY_BUT_MASK_SHIFT) {
180 ret |= Qt::ShiftModifier;
181 }
182 if (state & XCB_KEY_BUT_MASK_CONTROL) {
183 ret |= Qt::ControlModifier;
184 }
185 if (state & KKeyServer::modXAlt()) {
186 ret |= Qt::AltModifier;
187 }
188 if (state & KKeyServer::modXMeta()) {
189 ret |= Qt::MetaModifier;
190 }
191 return ret;
192}
193
194QPointF popupOffset(const QRectF &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSizeF popupSize)
195{
196 QPointF anchorPoint;
197 switch (anchorEdge & (Qt::LeftEdge | Qt::RightEdge)) {
198 case Qt::LeftEdge:
199 anchorPoint.setX(anchorRect.x());
200 break;
201 case Qt::RightEdge:
202 anchorPoint.setX(anchorRect.x() + anchorRect.width());
203 break;
204 default:
205 anchorPoint.setX(qRound(anchorRect.x() + anchorRect.width() / 2.0));
206 }
207 switch (anchorEdge & (Qt::TopEdge | Qt::BottomEdge)) {
208 case Qt::TopEdge:
209 anchorPoint.setY(anchorRect.y());
210 break;
211 case Qt::BottomEdge:
212 anchorPoint.setY(anchorRect.y() + anchorRect.height());
213 break;
214 default:
215 anchorPoint.setY(qRound(anchorRect.y() + anchorRect.height() / 2.0));
216 }
217
218 // calculate where the top left point of the popup will end up with the applied gravity
219 // gravity indicates direction. i.e if gravitating towards the top the popup's bottom edge
220 // will next to the anchor point
221 QPointF popupPosAdjust;
222 switch (gravity & (Qt::LeftEdge | Qt::RightEdge)) {
223 case Qt::LeftEdge:
224 popupPosAdjust.setX(-popupSize.width());
225 break;
226 case Qt::RightEdge:
227 popupPosAdjust.setX(0);
228 break;
229 default:
230 popupPosAdjust.setX(qRound(-popupSize.width() / 2.0));
231 }
232 switch (gravity & (Qt::TopEdge | Qt::BottomEdge)) {
233 case Qt::TopEdge:
234 popupPosAdjust.setY(-popupSize.height());
235 break;
236 case Qt::BottomEdge:
237 popupPosAdjust.setY(0);
238 break;
239 default:
240 popupPosAdjust.setY(qRound(-popupSize.height() / 2.0));
241 }
242
243 return anchorPoint + popupPosAdjust;
244}
245
246QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity)
247{
248 QRectF geometry = rect;
249
250 switch (gravity) {
251 case Gravity::TopLeft:
252 geometry.moveRight(bounds.right());
253 geometry.moveBottom(bounds.bottom());
254 break;
255 case Gravity::Top:
257 geometry.moveLeft(bounds.left());
258 geometry.moveBottom(bounds.bottom());
259 break;
260 case Gravity::Right:
262 case Gravity::Bottom:
263 case Gravity::None:
264 geometry.moveLeft(bounds.left());
265 geometry.moveTop(bounds.top());
266 break;
268 case Gravity::Left:
269 geometry.moveRight(bounds.right());
270 geometry.moveTop(bounds.top());
271 break;
272 }
273
274 return geometry;
275}
276
277} // namespace
278
279#ifndef KCMRULES
280#endif
StrutRect & operator=(const StrutRect &other)
Definition common.cpp:61
StrutArea area() const
Definition common.h:52
StrutRect(QRect rect=QRect(), StrutArea area=StrutAreaInvalid)
Definition common.cpp:43
Gravity
Definition globals.h:150
KWIN_EXPORT xcb_window_t rootWindow()
Definition xcb.h:24
Qt::MouseButtons x11ToQtMouseButtons(int state)
Definition common.cpp:155
Qt::MouseButton x11ToQtMouseButton(int button)
Definition common.cpp:135
StrutArea
Definition common.h:35
KWIN_EXPORT xcb_timestamp_t xTime()
Definition xcb.h:29
QPointF popupOffset(const QRectF &anchorRect, const Qt::Edges anchorEdge, const Qt::Edges gravity, const QSizeF popupSize)
Definition common.cpp:194
QRectF gravitateGeometry(const QRectF &rect, const QRectF &bounds, Gravity gravity)
Definition common.cpp:246
KWIN_EXPORT xcb_connection_t * connection()
Definition xcb.h:19
void KWIN_EXPORT ungrabXKeyboard()
Definition common.cpp:121
void KWIN_EXPORT grabXServer()
Definition common.cpp:72
Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
Definition common.cpp:176
void KWIN_EXPORT ungrabXServer()
Definition common.cpp:79
bool KWIN_EXPORT grabXKeyboard(xcb_window_t w=XCB_WINDOW_NONE)
Definition common.cpp:90
std::unique_ptr< T, CDeleter > UniqueCPtr
Definition c_ptr.h:28