43 QPixmap transparentPixmap(source.size());
44 transparentPixmap.fill(Qt::transparent);
45 QPainter p(&transparentPixmap);
46 p.setOpacity(opacity);
47 p.drawPixmap(0, 0, source);
48 return transparentPixmap;
67 QIcon Icon = DockManager::iconProvider().customIcon(iconId);
74 b->setIcon(b->style()->standardIcon(pixmap));
78 QPixmap normalPixmap = b->style()->standardPixmap(pixmap, 0, b);
80 Icon.addPixmap(normalPixmap, QIcon::Normal);
113 w->style()->unpolish(w);
114 w->style()->polish(w);
120 QList<QWidget *> childrens = w->findChildren<QWidget *>(
123 for (
auto c : childrens) {
124 c->style()->unpolish(c);
125 c->style()->polish(c);
135 while (splitter && splitter->isVisible()) {
139 splitter = internal::findParent<DockSplitter *>(splitter);
148 int index = splitter->indexOf(from);
149 from->setParent(
nullptr);
150 splitter->insertWidget(index, to);
193void setBackgroudColor(QWidget *w)
195 QPalette pe = w->palette();
196 if (qobject_cast<DockContainer *>(w)) {
197 pe.setColor(QPalette::Window, Qt::red);
198 }
else if (qobject_cast<DockPanel *>(w)) {
199 pe.setColor(QPalette::Window, Qt::green);
200 }
else if (qobject_cast<DockWidget *>(w)) {
201 pe.setColor(QPalette::Window, Qt::blue);
203 pe.setColor(QPalette::Window, Qt::yellow);
206 w->setAutoFillBackground(
true);
207 w->layout()->setContentsMargins(2, 2, 2, 2);
212static QString _window_manager;
213static QHash<QString, xcb_atom_t> _xcb_atom_cache;
215bool is_platform_x11()
217 return QGuiApplication::platformName() == QLatin1String(
"xcb");
220xcb_connection_t *x11_connection()
224 QPlatformNativeInterface *native = qApp->platformNativeInterface();
228 void *connection = native->nativeResourceForIntegration(QByteArray(
"connection"));
229 return reinterpret_cast<xcb_connection_t *
>(connection);
232xcb_atom_t xcb_get_atom(
const char *
name)
234 if (!is_platform_x11()) {
235 return XCB_ATOM_NONE;
237 auto key = QString(
name);
238 if (_xcb_atom_cache.contains(key)) {
239 return _xcb_atom_cache[key];
241 xcb_connection_t *connection = x11_connection();
242 xcb_intern_atom_cookie_t request = xcb_intern_atom(connection, 1, strlen(
name),
name);
243 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, request,
nullptr);
245 return XCB_ATOM_NONE;
247 xcb_atom_t atom = reply->atom;
248 if (atom == XCB_ATOM_NONE) {
251 _xcb_atom_cache.insert(key, atom);
257void xcb_update_prop(
bool set, WId
window,
const char *type,
const char *prop,
const char *prop2)
259 auto connection = x11_connection();
260 xcb_atom_t type_atom = xcb_get_atom(type);
261 xcb_atom_t prop_atom = xcb_get_atom(prop);
262 xcb_client_message_event_t event;
263 event.response_type = XCB_CLIENT_MESSAGE;
267 event.type = type_atom;
268 event.data.data32[0] = set ? 1 : 0;
269 event.data.data32[1] = prop_atom;
270 event.data.data32[2] = prop2 ? xcb_get_atom(prop2) : 0;
271 event.data.data32[3] = 0;
272 event.data.data32[4] = 0;
274 xcb_send_event(connection, 0,
window,
275 XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
276 XCB_EVENT_MASK_PROPERTY_CHANGE,
277 (
const char *)&event);
278 xcb_flush(connection);
281xcb_get_property_reply_t *_xcb_get_props(WId
window,
const char *type,
unsigned int atom_type)
283 if (!is_platform_x11()) {
286 xcb_connection_t *connection = x11_connection();
287 xcb_atom_t type_atom = xcb_get_atom(type);
288 if (type_atom == XCB_ATOM_NONE) {
291 xcb_get_property_cookie_t request =
292 xcb_get_property_unchecked(connection, 0,
window, type_atom, atom_type, 0, 1024);
293 xcb_get_property_reply_t *reply = xcb_get_property_reply(connection, request,
nullptr);
294 if (reply && reply->type != atom_type) {
295 QX_DOCK_PRINT(
"ATOM TYPE MISMATCH (" << type <<
"). Expected: " << atom_type <<
" but got " << reply->type);
302template <
typename T>
void xcb_get_prop_list(WId
window,
const char *type, QVector<T> &ret,
unsigned int atom_type)
304 xcb_get_property_reply_t *reply = _xcb_get_props(
window, type, atom_type);
305 if (reply && reply->format == 32 && reply->type == atom_type && reply->value_len > 0) {
306 const xcb_atom_t *data =
static_cast<const T *
>(xcb_get_property_value(reply));
307 ret.resize(reply->value_len);
308 memcpy((
void *)&ret.first(), (
void *)data, reply->value_len *
sizeof(T));
313QString xcb_get_prop_string(WId
window,
const char *type)
317 xcb_atom_t utf_atom = xcb_get_atom(
"UTF8_STRING");
318 if (utf_atom != XCB_ATOM_NONE) {
319 xcb_get_property_reply_t *reply = _xcb_get_props(
window, type, utf_atom);
320 if (reply && reply->format == 8 && reply->type == utf_atom) {
321 const char *value =
reinterpret_cast<const char *
>(xcb_get_property_value(reply));
322 ret = QString::fromUtf8(value, xcb_get_property_value_length(reply));
329 xcb_get_property_reply_t *reply = _xcb_get_props(
window, type, XCB_ATOM_STRING);
330 if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
331 const char *value =
reinterpret_cast<const char *
>(xcb_get_property_value(reply));
332 ret = QString::fromLatin1(value, xcb_get_property_value_length(reply));
338bool xcb_dump_props(WId
window,
const char *type)
340 QVector<xcb_atom_t> atoms;
341 xcb_get_prop_list(
window, type, atoms, XCB_ATOM_ATOM);
342 qDebug() <<
"\n\n!!!" << type <<
" - " << atoms.length();
343 xcb_connection_t *connection = x11_connection();
344 for (
auto atom : atoms) {
345 auto foo = xcb_get_atom_name(connection, atom);
346 auto bar = xcb_get_atom_name_reply(connection, foo,
nullptr);
347 qDebug() <<
"\t" << xcb_get_atom_name_name(bar);
353void xcb_add_prop(
bool state, WId
window,
const char *type,
const char *prop)
355 if (!is_platform_x11()) {
358 xcb_atom_t prop_atom = xcb_get_atom(prop);
359 xcb_atom_t type_atom = xcb_get_atom(type);
360 if (prop_atom == XCB_ATOM_NONE || type_atom == XCB_ATOM_NONE) {
363 QVector<xcb_atom_t> atoms;
364 xcb_get_prop_list(
window, type, atoms, XCB_ATOM_ATOM);
365 int index = atoms.indexOf(prop_atom);
366 if (state && index == -1) {
367 atoms.push_back(prop_atom);
368 }
else if (!state && index >= 0) {
371 xcb_connection_t *connection = x11_connection();
372 xcb_change_property(connection, XCB_PROP_MODE_REPLACE,
window, type_atom, XCB_ATOM_ATOM, 32, atoms.count(),
374 xcb_flush(connection);
377QString detectWindowManagerX11()
381 if (!is_platform_x11()) {
384 xcb_connection_t *connection = x11_connection();
385 xcb_screen_t *first_screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
391 xcb_window_t root = first_screen->root;
392 xcb_window_t support_win = 0;
393 QVector<xcb_window_t> sup_windows;
394 xcb_get_prop_list(root,
"_NET_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_WINDOW);
395 if (sup_windows.length() == 0) {
398 xcb_get_prop_list(root,
"_WIN_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_CARDINAL);
400 if (sup_windows.length() == 0) {
401 QX_DOCK_PRINT(
"Failed to get the supporting window on non EWMH comform WM.");
404 support_win = sup_windows[0];
405 QString ret = xcb_get_prop_string(support_win,
"_NET_WM_NAME");
406 if (ret.length() == 0) {
413QString windowManager()
415 if (_window_manager.length() == 0) {
416 _window_manager = detectWindowManagerX11();
418 return _window_manager;