utils.cpp 4.39 KB
Newer Older
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
1
2
3
/*
    KWin - the KDE window manager
    This file is part of the KDE project.
4

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
5
6
    SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
    SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
7

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
8
9
    SPDX-License-Identifier: GPL-2.0-or-later
*/
10
11
12
13
14
15
16
17
18

/*

 This file is for (very) small utility functions/classes.

*/

#include "utils.h"

Martin Flöser's avatar
Martin Flöser committed
19
#include <QWidget>
20
#include <kkeyserver.h>
21
22

#ifndef KCMRULES
23
#include <QApplication>
Martin Flöser's avatar
Martin Flöser committed
24
#include <QDebug>
25
26

#include "atoms.h"
27
#include "platform.h"
28
29
#include "workspace.h"

30
31
#include <csignal>
#include <cstdio>
32

33
34
#endif

35
Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core", QtCriticalMsg)
36
Q_LOGGING_CATEGORY(KWIN_VIRTUALKEYBOARD, "kwin_virtualkeyboard", QtCriticalMsg)
37
38
39
40
41
namespace KWin
{

#ifndef KCMRULES

42
43
44
45
//************************************
// StrutRect
//************************************

46
47
48
49
50
StrutRect::StrutRect(QRect rect, StrutArea area)
    : QRect(rect)
    , m_area(area)
{
}
51

52
53
54
55
56
StrutRect::StrutRect(const StrutRect& other)
    : QRect(other)
    , m_area(other.area())
{
}
57

58
59
60
61
62
63
64
65
66
StrutRect &StrutRect::operator=(const StrutRect &other)
{
    if (this != &other) {
        QRect::operator=(other);
        m_area = other.area();
    }
    return *this;
}

67
68
#endif

69
70
71
72
73
74
75
Process::Process(QObject *parent)
    : QProcess(parent)
{
}

Process::~Process() = default;

76
#ifndef KCMRULES
77
void updateXTime()
78
{
79
    kwinApp()->platform()->updateXTime();
80
}
81
82
83
84

static int server_grab_count = 0;

void grabXServer()
85
86
{
    if (++server_grab_count == 1)
Martin Flöser's avatar
Martin Flöser committed
87
        xcb_grab_server(connection());
88
}
89
90

void ungrabXServer()
91
{
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
92
    Q_ASSERT(server_grab_count > 0);
93
    if (--server_grab_count == 0) {
Martin Flöser's avatar
Martin Flöser committed
94
95
        xcb_ungrab_server(connection());
        xcb_flush(connection());
96
    }
97
}
98
99
100

static bool keyboard_grabbed = false;

Martin Flöser's avatar
Martin Flöser committed
101
bool grabXKeyboard(xcb_window_t w)
102
{
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
103
    if (QWidget::keyboardGrabber() != nullptr)
104
        return false;
105
    if (keyboard_grabbed)
106
        return false;
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
107
    if (qApp->activePopupWidget() != nullptr)
108
        return false;
Martin Flöser's avatar
Martin Flöser committed
109
    if (w == XCB_WINDOW_NONE)
110
        w = rootWindow();
Martin Flöser's avatar
Martin Flöser committed
111
112
    const xcb_grab_keyboard_cookie_t c = xcb_grab_keyboard_unchecked(connection(), false, w, xTime(),
                                                                     XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
113
    ScopedCPointer<xcb_grab_keyboard_reply_t> grab(xcb_grab_keyboard_reply(connection(), c, nullptr));
Martin Flöser's avatar
Martin Flöser committed
114
    if (grab.isNull()) {
115
        return false;
Martin Flöser's avatar
Martin Flöser committed
116
117
118
119
    }
    if (grab->status != XCB_GRAB_STATUS_SUCCESS) {
        return false;
    }
120
121
    keyboard_grabbed = true;
    return true;
122
}
123
124

void ungrabXKeyboard()
125
126
127
{
    if (!keyboard_grabbed) {
        // grabXKeyboard() may fail sometimes, so don't fail, but at least warn anyway
128
        qCDebug(KWIN_CORE) << "ungrabXKeyboard() called but keyboard not grabbed!";
129
    }
130
    keyboard_grabbed = false;
Martin Flöser's avatar
Martin Flöser committed
131
    xcb_ungrab_keyboard(connection(), XCB_TIME_CURRENT_TIME);
132
}
133

134
135
136
137
138
139
140
141
142
void Process::setupChildProcess()
{
    sigset_t userSiganls;
    sigemptyset(&userSiganls);
    sigaddset(&userSiganls, SIGUSR1);
    sigaddset(&userSiganls, SIGUSR2);
    pthread_sigmask(SIG_UNBLOCK, &userSiganls, nullptr);
}

143
#endif
144
145
146

// converting between X11 mouse/keyboard state mask and Qt button/keyboard states

147
148
Qt::MouseButton x11ToQtMouseButton(int button)
{
149
    if (button == XCB_BUTTON_INDEX_1)
150
        return Qt::LeftButton;
151
    if (button == XCB_BUTTON_INDEX_2)
152
        return Qt::MiddleButton;
153
    if (button == XCB_BUTTON_INDEX_3)
154
        return Qt::RightButton;
155
    if (button == XCB_BUTTON_INDEX_4)
156
        return Qt::XButton1;
157
    if (button == XCB_BUTTON_INDEX_5)
158
        return Qt::XButton2;
159
    return Qt::NoButton;
160
}
161

162
163
Qt::MouseButtons x11ToQtMouseButtons(int state)
{
164
    Qt::MouseButtons ret = {};
165
    if (state & XCB_KEY_BUT_MASK_BUTTON_1)
166
        ret |= Qt::LeftButton;
167
    if (state & XCB_KEY_BUT_MASK_BUTTON_2)
168
        ret |= Qt::MiddleButton;
169
    if (state & XCB_KEY_BUT_MASK_BUTTON_3)
170
        ret |= Qt::RightButton;
171
    if (state & XCB_KEY_BUT_MASK_BUTTON_4)
172
        ret |= Qt::XButton1;
173
    if (state & XCB_KEY_BUT_MASK_BUTTON_5)
174
        ret |= Qt::XButton2;
175
    return ret;
176
}
177

178
179
Qt::KeyboardModifiers x11ToQtKeyboardModifiers(int state)
{
180
    Qt::KeyboardModifiers ret = {};
181
    if (state & XCB_KEY_BUT_MASK_SHIFT)
182
        ret |= Qt::ShiftModifier;
183
    if (state & XCB_KEY_BUT_MASK_CONTROL)
184
        ret |= Qt::ControlModifier;
185
    if (state & KKeyServer::modXAlt())
186
        ret |= Qt::AltModifier;
187
    if (state & KKeyServer::modXMeta())
188
189
        ret |= Qt::MetaModifier;
    return ret;
190
}
191
192
193
194
195

} // namespace

#ifndef KCMRULES
#endif