Changeset View
Changeset View
Standalone View
Standalone View
shell/screenpool.cpp
Show All 12 Lines | |||||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | 14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the | 15 | * License along with this program; if not, write to the | ||
16 | * Free Software Foundation, Inc., | 16 | * Free Software Foundation, Inc., | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
18 | */ | 18 | */ | ||
19 | 19 | | |||
20 | #include "screenpool.h" | 20 | #include "screenpool.h" | ||
21 | #include <config-plasma.h> | ||||
21 | 22 | | |||
22 | #include <QGuiApplication> | 23 | #include <QGuiApplication> | ||
23 | #include <QScreen> | 24 | #include <QScreen> | ||
24 | 25 | | |||
26 | #if HAVE_X11 | ||||
27 | #include <QtX11Extras/QX11Info> | ||||
28 | #include <xcb/xcb.h> | ||||
29 | #include <xcb/randr.h> | ||||
30 | #include <xcb/xcb_event.h> | ||||
31 | #endif | ||||
32 | | ||||
25 | ScreenPool::ScreenPool(KSharedConfig::Ptr config, QObject *parent) | 33 | ScreenPool::ScreenPool(KSharedConfig::Ptr config, QObject *parent) | ||
26 | : QObject(parent), | 34 | : QObject(parent), | ||
27 | m_configGroup(KConfigGroup(config, QStringLiteral("ScreenConnectors"))) | 35 | m_configGroup(KConfigGroup(config, QStringLiteral("ScreenConnectors"))) | ||
28 | { | 36 | { | ||
37 | qApp->installNativeEventFilter(this); | ||||
broulik: No need to install if not on X? | |||||
38 | | ||||
29 | m_configSaveTimer.setSingleShot(true); | 39 | m_configSaveTimer.setSingleShot(true); | ||
30 | connect(&m_configSaveTimer, &QTimer::timeout, this, [this](){ | 40 | connect(&m_configSaveTimer, &QTimer::timeout, this, [this](){ | ||
31 | m_configGroup.sync(); | 41 | m_configGroup.sync(); | ||
32 | }); | 42 | }); | ||
33 | } | 43 | } | ||
34 | 44 | | |||
35 | void ScreenPool::load() | 45 | void ScreenPool::load() | ||
36 | { | 46 | { | ||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Line(s) | 153 | { | |||
154 | return i; | 164 | return i; | ||
155 | } | 165 | } | ||
156 | 166 | | |||
157 | QList <int> ScreenPool::knownIds() const | 167 | QList <int> ScreenPool::knownIds() const | ||
158 | { | 168 | { | ||
159 | return m_connectorForId.keys(); | 169 | return m_connectorForId.keys(); | ||
160 | } | 170 | } | ||
161 | 171 | | |||
172 | bool ScreenPool::nativeEventFilter(const QByteArray& eventType, void* message, long int* result) | ||||
173 | { | ||||
174 | Q_UNUSED(result); | ||||
175 | #if HAVE_X11 | ||||
176 | // a particular edge case: when we switch the only enabled screen | ||||
177 | // we don't have any signal about it, the primary screen changes but we have the same old QScreen* getting recycled | ||||
178 | // see https://bugs.kde.org/show_bug.cgi?id=373880 | ||||
179 | // if this slot will be invoked many times, their//second time on will do nothing as name and primaryconnector will be the same by then | ||||
180 | if (eventType != "xcb_generic_event_t") { | ||||
181 | return false; | ||||
182 | } | ||||
183 | | ||||
184 | xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); | ||||
185 | | ||||
186 | const auto responseType = XCB_EVENT_RESPONSE_TYPE(ev); | ||||
187 | | ||||
188 | const xcb_query_extension_reply_t* reply = xcb_get_extension_data(QX11Info::connection(), &xcb_randr_id); | ||||
Is that call to X really neccessary everytime? It's called constantly for all kinds of events. Also at least cache the QX11Info::connection() ... broulik: Is that call to X really neccessary everytime? It's called constantly for all kinds of events. | |||||
189 | | ||||
190 | if (responseType == reply->first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { | ||||
191 | if (qGuiApp->primaryScreen()->name() != primaryConnector()) { | ||||
192 | //new screen? | ||||
193 | if (id(qGuiApp->primaryScreen()->name()) < 0) { | ||||
194 | insertScreenMapping(firstAvailableId(), qGuiApp->primaryScreen()->name()); | ||||
195 | } | ||||
196 | //switch the primary screen in the pool | ||||
197 | setPrimaryConnector(qGuiApp->primaryScreen()->name()); | ||||
198 | } | ||||
199 | } | ||||
200 | #endif | ||||
201 | return false; | ||||
202 | } | ||||
203 | | ||||
Wondering whether returning false always is correct. It feels wrong but I may be missing something. pmuralidharan: Wondering whether returning false always is correct. It feels wrong but I may be missing… | |||||
always returning false means you don't want to ever block such events from further management, which is correct. mart: always returning false means you don't want to ever block such events from further management… | |||||
204 | | ||||
162 | #include "moc_screenpool.cpp" | 205 | #include "moc_screenpool.cpp" | ||
163 | 206 | |
No need to install if not on X?