Changeset View
Changeset View
Standalone View
Standalone View
xembed-sni-proxy/fdoselectionmanager.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Registers as a embed container | 2 | * Registers as a embed container | ||
3 | * Copyright (C) 2015 <davidedmundson@kde.org> David Edmundson | 3 | * Copyright (C) 2015 <davidedmundson@kde.org> David Edmundson | ||
4 | * Copyright (C) 2019 <materka@gmail.com> Konrad Materka | ||||
4 | * | 5 | * | ||
5 | * This library is free software; you can redistribute it and/or | 6 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | 7 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | 8 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | 9 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | 10 | * | ||
10 | * This library is distributed in the hope that it will be useful, | 11 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | 14 | * Lesser General Public License for more details. | ||
14 | * | 15 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | 16 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; if not, write to the Free Software | 17 | * License along with this library; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | * | 19 | * | ||
19 | */ | 20 | */ | ||
20 | #include "fdoselectionmanager.h" | 21 | #include "fdoselectionmanager.h" | ||
21 | 22 | | |||
22 | #include "debug.h" | 23 | #include "debug.h" | ||
23 | 24 | | |||
24 | #include <QCoreApplication> | 25 | #include <QCoreApplication> | ||
25 | #include <QDBusConnection> | | |||
26 | #include <QDBusServiceWatcher> | | |||
27 | #include <QHash> | | |||
28 | #include <QTimer> | 26 | #include <QTimer> | ||
29 | #include <QTextDocument> | | |||
30 | #include <QX11Info> | 27 | #include <QX11Info> | ||
31 | 28 | | |||
32 | #include <KSelectionOwner> | 29 | #include <KSelectionOwner> | ||
33 | 30 | | |||
34 | #include <xcb/xcb.h> | 31 | #include <xcb/xcb.h> | ||
35 | #include <xcb/xcb_atom.h> | 32 | #include <xcb/xcb_atom.h> | ||
36 | #include <xcb/xcb_event.h> | 33 | #include <xcb/xcb_event.h> | ||
37 | #include <xcb/composite.h> | 34 | #include <xcb/composite.h> | ||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Line(s) | 154 | } else if (responseType == XCB_CONFIGURE_REQUEST) { | |||
158 | const auto event = reinterpret_cast<xcb_configure_request_event_t *>(ev); | 155 | const auto event = reinterpret_cast<xcb_configure_request_event_t *>(ev); | ||
159 | const auto sniProxy = m_proxies.value(event->window); | 156 | const auto sniProxy = m_proxies.value(event->window); | ||
160 | if (sniProxy) { | 157 | if (sniProxy) { | ||
161 | // The embedded window tries to move or resize. Ignore move, handle resize only. | 158 | // The embedded window tries to move or resize. Ignore move, handle resize only. | ||
162 | if ((event->value_mask & XCB_CONFIG_WINDOW_WIDTH) || (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT)) { | 159 | if ((event->value_mask & XCB_CONFIG_WINDOW_WIDTH) || (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT)) { | ||
163 | sniProxy->resizeWindow(event->width, event->height); | 160 | sniProxy->resizeWindow(event->width, event->height); | ||
164 | } | 161 | } | ||
165 | } | 162 | } | ||
163 | } else if (responseType == XCB_VISIBILITY_NOTIFY) { | ||||
164 | const auto event = reinterpret_cast<xcb_visibility_notify_event_t *>(ev); | ||||
165 | // it's possible that something showed our container window, we have to hide it | ||||
166 | // workaround for BUG 357443: when KWin is restarted, container window is shown on top | ||||
167 | if (event->state == XCB_VISIBILITY_UNOBSCURED) { | ||||
kmaterka: XCB_VISIBILITY_UNOBSCURED is rare. During simulated click (when we stack window above)… | |||||
168 | for (auto sniProxy : m_proxies.values()) { | ||||
Iteration sucks, but this is the simplest (a in most cases the quickest) method. In this event we receive container window id, we can get its child and get sniproxy using it: xcb_connection_t *c = QX11Info::connection(); xcb_query_tree_cookie_t cookie = xcb_query_tree(c, event->window); QScopedPointer<xcb_query_tree_reply_t, QScopedPointerPodDeleter> reply(xcb_query_tree_reply(c, cookie, nullptr)); if (reply && xcb_query_tree_children_length(reply.data()) == 1) { xcb_window_t *children = xcb_query_tree_children(reply.data()); const auto sniProxy = m_proxies.value(children[0]); if (sniProxy) { sniProxy->handleExposeEvent(event->window); } } IMO this is slower. The best would be to have second map like m_proxies, but with container windows id (or something similar in the idea). kmaterka: Iteration sucks, but this is the simplest (a in most cases the quickest) method. In this event… | |||||
169 | sniProxy->hideContainerWindow(event->window); | ||||
170 | } | ||||
171 | } | ||||
166 | } | 172 | } | ||
167 | 173 | | |||
168 | return false; | 174 | return false; | ||
169 | } | 175 | } | ||
170 | 176 | | |||
171 | void FdoSelectionManager::dock(xcb_window_t winId) | 177 | void FdoSelectionManager::dock(xcb_window_t winId) | ||
172 | { | 178 | { | ||
173 | qCDebug(SNIPROXY) << "trying to dock window " << winId; | 179 | qCDebug(SNIPROXY) << "trying to dock window " << winId; | ||
Show All 18 Lines | 191 | { | |||
192 | m_proxies.remove(winId); | 198 | m_proxies.remove(winId); | ||
193 | } | 199 | } | ||
194 | 200 | | |||
195 | void FdoSelectionManager::onClaimedOwnership() | 201 | void FdoSelectionManager::onClaimedOwnership() | ||
196 | { | 202 | { | ||
197 | qCDebug(SNIPROXY) << "Manager selection claimed"; | 203 | qCDebug(SNIPROXY) << "Manager selection claimed"; | ||
198 | 204 | | |||
199 | setSystemTrayVisual(); | 205 | setSystemTrayVisual(); | ||
200 | | ||||
201 | // send all container windows to background on KWin restart | | |||
202 | QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QStringLiteral("org.kde.KWin"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); | | |||
203 | connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, [=](const QString &) { | | |||
204 | // some delay is necesary | | |||
205 | QTimer::singleShot(100, this, [=]() { | | |||
206 | for (auto sniproxy : m_proxies) { | | |||
207 | sniproxy->stackContainerWindow(XCB_STACK_MODE_BELOW); | | |||
208 | } | | |||
209 | }); | | |||
210 | }); | | |||
211 | } | 206 | } | ||
212 | 207 | | |||
213 | void FdoSelectionManager::onFailedToClaimOwnership() | 208 | void FdoSelectionManager::onFailedToClaimOwnership() | ||
214 | { | 209 | { | ||
215 | qCWarning(SNIPROXY) << "failed to claim ownership of Systray Manager"; | 210 | qCWarning(SNIPROXY) << "failed to claim ownership of Systray Manager"; | ||
216 | qApp->exit(-1); | 211 | qApp->exit(-1); | ||
217 | } | 212 | } | ||
218 | 213 | | |||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |
XCB_VISIBILITY_UNOBSCURED is rare. During simulated click (when we stack window above) xembedsniproxy receives XCB_VISIBILITY_PARTIALLY_OBSCURED. Obviously we ignore the last possible case: XCB_VISIBILITY_FULLY_OBSCURED.