LeechCraft 0.6.70-19214-g121e5318a7
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
xwrapper.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#include "xwrapper.h"
10#include <limits>
11#include <memory>
12#include <type_traits>
13#include <bit>
14#include <QString>
15#include <QPixmap>
16#include <QIcon>
17#include <QApplication>
18#include <QWidget>
19#include <QAbstractEventDispatcher>
20#include <QtDebug>
21#include <QScreen>
22#include <X11/Xlib.h>
23#include <X11/Xutil.h>
24#include <X11/Xatom.h>
25#include <xcb/xcb.h>
26#include <util/sll/qtutil.h>
27
28namespace LC::Util
29{
30 const int SourcePager = 2;
31
32 const int StateRemove = 0;
33 const int StateAdd = 1;
34
35 XWrapper::XWrapper (xcb_connection_t *conn, Display *display, PrivateCtor)
36 : Conn_ { conn }
37 , Display_ { display }
38 , AppWin_ { DefaultRootWindow (display) }
39 {
40 QAbstractEventDispatcher::instance ()->installNativeEventFilter (this);
41
42 const uint32_t rootEvents [] =
43 {
44 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
45 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
46 XCB_EVENT_MASK_PROPERTY_CHANGE
47 };
48 xcb_change_window_attributes (Conn_,
49 AppWin_, XCB_CW_EVENT_MASK, rootEvents);
50 }
51
52 std::optional<XWrapper&> XWrapper::Instance ()
53 {
54 static const auto wrapper = [] () -> std::unique_ptr<XWrapper>
55 {
56 const auto x11app = qGuiApp->nativeInterface<QNativeInterface::QX11Application> ();
57 if (!x11app || !x11app->display ())
58 return {};
59
60 return std::make_unique<XWrapper> (x11app->connection (), x11app->display (), PrivateCtor {});
61 } ();
62 if (!wrapper)
63 return {};
64 return *wrapper;
65 }
66
67 xcb_connection_t* XWrapper::GetConnection () const
68 {
69 return Conn_;
70 }
71
73 {
74 return Display_;
75 }
76
78 {
79 return AppWin_;
80 }
81
82 bool XWrapper::nativeEventFilter (const QByteArray& eventType, void *msg, qintptr*)
83 {
84 if (eventType != "xcb_generic_event_t")
85 return false;
86
87 const auto ev = static_cast<xcb_generic_event_t*> (msg);
88 if ((ev->response_type & ~0x80) == XCB_PROPERTY_NOTIFY)
89 HandlePropNotify (static_cast<xcb_property_notify_event_t*> (msg));
90
91 return false;
92 }
93
94 namespace
95 {
96 template<typename T>
97 struct IsDoublePtr : std::false_type {};
98
99 template<typename T>
100 struct IsDoublePtr<T**> : std::true_type {};
101
102 template<typename T>
103 class Guarded
104 {
105 T *Data_ = nullptr;
106 public:
107 Guarded () = default;
108
109 Guarded (const Guarded&) = delete;
110 Guarded& operator= (const Guarded&) = delete;
111
112 Guarded (Guarded&& other) noexcept
113 : Data_ { other.Data_ }
114 {
115 other.Data_ = nullptr;
116 }
117
118 Guarded& operator= (Guarded&& other) noexcept
119 {
120 std::swap (Data_, other.Data_);
121 return *this;
122 }
123
124 ~Guarded () noexcept
125 {
126 if (Data_)
127 XFree (Data_);
128 }
129
130 T** Get (bool clear = true) noexcept
131 {
132 if (clear && Data_)
133 XFree (Data_);
134 return &Data_;
135 }
136
137 template<typename U>
138 U GetAs (bool clear = true) noexcept
139 {
140 if (clear && Data_)
141 XFree (Data_);
142 return IsDoublePtr<U>::value ?
143 reinterpret_cast<U> (&Data_) :
144 reinterpret_cast<U> (Data_);
145 }
146
147 T operator[] (size_t idx) const noexcept
148 {
149 return Data_ [idx];
150 }
151
152 T& operator[] (size_t idx) noexcept
153 {
154 return Data_ [idx];
155 }
156
157 explicit operator bool () const noexcept
158 {
159 return Data_ != nullptr;
160 }
161
162 bool operator! () const noexcept
163 {
164 return !Data_;
165 }
166 };
167 }
168
170 {
171 XFlush (Display_);
172 XSync (Display_, False);
173 }
174
176 {
177 ulong length = 0;
178 Guarded<Window> data;
179
180 QList<Window> result;
181 if (GetRootWinProp (GetAtom ("_NET_CLIENT_LIST"), &length, data.GetAs<uchar**> ()))
182 for (ulong i = 0; i < length; ++i)
183 result << data [i];
184 return result;
185 }
186
188 {
189 QString name;
190
191 ulong length = 0;
192 Guarded<uchar> data;
193
194 auto utf8Str = GetAtom ("UTF8_STRING");
195
196 if (GetWinProp (wid, GetAtom ("_NET_WM_VISIBLE_NAME"), &length, data.Get (), utf8Str))
197 name = QString::fromUtf8 (data.GetAs<char*> (false));
198
199 if (name.isEmpty () && GetWinProp (wid, GetAtom ("_NET_WM_NAME"), &length, data.Get (), utf8Str))
200 name = QString::fromUtf8 (data.GetAs<char*> (false));
201
202 if (name.isEmpty () && GetWinProp (wid, GetAtom ("XA_WM_NAME"), &length, data.Get (), XA_STRING))
203 name = QString::fromUtf8 (data.GetAs<char*> (false));
204
205 if (name.isEmpty ())
206 {
207 XFetchName (Display_, wid, data.GetAs<char**> ());
208 name = QString (data.GetAs<char*> (false));
209 }
210
211 if (name.isEmpty ())
212 {
213 XTextProperty prop;
214 if (XGetWMName (Display_, wid, &prop))
215 {
216 name = QString::fromUtf8 (reinterpret_cast<char*> (prop.value));
217 XFree (prop.value);
218 }
219 }
220
221 return name;
222 }
223
225 {
226 int fmt = 0;
227 ulong type, count, extra;
228 Guarded<ulong> data;
229
230 XGetWindowProperty (Display_, wid, GetAtom ("_NET_WM_ICON"),
231 0, std::numeric_limits<long>::max (), False, AnyPropertyType,
232 &type, &fmt, &count, &extra,
233 data.GetAs<uchar**> ());
234
235 if (!data)
236 return {};
237
238 QIcon icon;
239
240 auto cur = *data.Get (false);
241 auto end = cur + count;
242 while (cur < end)
243 {
244 QImage img (cur [0], cur [1], QImage::Format_ARGB32);
245 cur += 2;
246 const auto bytesCount = img.sizeInBytes ();
247 for (int i = 0; i < bytesCount / 4; ++i, ++cur)
248 reinterpret_cast<uint*> (img.bits ()) [i] = *cur;
249
250 icon.addPixmap (QPixmap::fromImage (img));
251 }
252
253 return icon;
254 }
255
256 template<typename Flag>
257 QFlags<Flag> XWrapper::GetFlagsList (Window wid, Atom property, const QHash<Atom, Flag>& atom2flag) const
258 {
259 QFlags<Flag> result;
260
261 ulong length = 0;
262 ulong *data = 0;
263 if (!GetWinProp (wid, property, &length, reinterpret_cast<uchar**> (&data), XA_ATOM))
264 return result;
265
266 for (ulong i = 0; i < length; ++i)
267 result |= atom2flag.value (data [i], static_cast<Flag> (0));
268
269 XFree (data);
270
271 return result;
272 }
273
275 {
276 auto get = [this] (const QByteArray& atom) { return GetAtom (AsStringView ("_NET_WM_STATE_" + atom)); };
277 static const QHash<Atom, WinStateFlag> atom2flag
278 {
279 { get ("MODAL"), WinStateFlag::Modal },
280 { get ("STICKY"), WinStateFlag::Sticky },
281 { get ("MAXIMIZED_VERT"), WinStateFlag::MaximizedVert },
282 { get ("MAXIMIZED_HORZ"), WinStateFlag::MaximizedHorz },
283 { get ("SHADED"), WinStateFlag::Shaded },
284 { get ("SKIP_TASKBAR"), WinStateFlag::SkipTaskbar },
285 { get ("SKIP_PAGER"), WinStateFlag::SkipPager },
286 { get ("HIDDEN"), WinStateFlag::Hidden },
287 { get ("FULLSCREEN"), WinStateFlag::Fullscreen },
288 { get ("ABOVE"), WinStateFlag::OnTop },
289 { get ("BELOW"), WinStateFlag::OnBottom },
290 { get ("DEMANDS_ATTENTION"), WinStateFlag::Attention },
291 };
292
293 return GetFlagsList (wid, GetAtom ("_NET_WM_STATE"), atom2flag);
294 }
295
296 AllowedActionFlags XWrapper::GetWindowActions (Window wid)
297 {
298 auto get = [this] (const QByteArray& atom) { return GetAtom (AsStringView ("_NET_WM_ACTION_" + atom)); };
299 static const QHash<Atom, AllowedActionFlag> atom2flag
300 {
301 { get ("MOVE"), AllowedActionFlag::Move },
302 { get ("RESIZE"), AllowedActionFlag::Resize },
303 { get ("MINIMIZE"), AllowedActionFlag::Minimize },
304 { get ("SHADE"), AllowedActionFlag::Shade },
305 { get ("STICK"), AllowedActionFlag::Stick },
306 { get ("MAXIMIZE_HORZ"), AllowedActionFlag::MaximizeHorz },
307 { get ("MAXIMIZE_VERT"), AllowedActionFlag::MaximizeVert },
308 { get ("FULLSCREEN"), AllowedActionFlag::ShowFullscreen },
309 { get ("CHANGE_DESKTOP"), AllowedActionFlag::ChangeDesktop },
310 { get ("CLOSE"), AllowedActionFlag::Close },
311 { get ("ABOVE"), AllowedActionFlag::MoveToTop },
312 { get ("BELOW"), AllowedActionFlag::MoveToBottom },
313 };
314
315 return GetFlagsList (wid, GetAtom ("_NET_WM_ALLOWED_ACTIONS"), atom2flag);
316 }
317
319 {
320 auto win = GetActiveWindow ();
321 if (!win)
322 return 0;
323
324 Window transient = None;
325 if (!ShouldShow (win) && XGetTransientForHint (Display_, win, &transient))
326 return transient;
327
328 return win;
329 }
330
332 {
333 ulong length = 0;
334 Guarded<uchar> data;
335 return GetWinProp (wid, GetAtom ("WM_CLASS"), &length, data.Get ()) &&
336 QString (data.GetAs<char*> (false)).startsWith ("leechcraft"_ql);
337 }
338
340 {
341 static const QList<Atom> ignoreAtoms
342 {
343 GetAtom ("_NET_WM_WINDOW_TYPE_DESKTOP"),
344 GetAtom ("_NET_WM_WINDOW_TYPE_DOCK"),
345 GetAtom ("_NET_WM_WINDOW_TYPE_TOOLBAR"),
346 GetAtom ("_NET_WM_WINDOW_TYPE_UTILITY"),
347 GetAtom ("_NET_WM_WINDOW_TYPE_MENU"),
348 GetAtom ("_NET_WM_WINDOW_TYPE_SPLASH"),
349 GetAtom ("_NET_WM_WINDOW_TYPE_POPUP_MENU")
350 };
351
352 for (const auto& type : GetWindowType (wid))
353 if (ignoreAtoms.contains (type))
354 return false;
355
357 return false;
358
359 Window transient = None;
360 if (!XGetTransientForHint (Display_, wid, &transient))
361 return true;
362
363 if (transient == 0 || transient == wid || transient == AppWin_)
364 return true;
365
366 return !GetWindowType (transient).contains (GetAtom ("_NET_WM_WINDOW_TYPE_NORMAL"));
367 }
368
370 {
371 if (IsLCWindow (wid))
372 return;
373
374 XSelectInput (Display_, wid, PropertyChangeMask);
375 }
376
377 void XWrapper::SetStrut (QWidget *widget, Qt::ToolBarArea area)
378 {
379 const auto wid = widget->effectiveWinId ();
380
381 const auto& winGeom = widget->geometry ();
382
383 switch (area)
384 {
385 case Qt::BottomToolBarArea:
386 SetStrut (wid,
387 0, 0, 0, winGeom.height (),
388 0, 0,
389 0, 0,
390 0, 0,
391 winGeom.left (), winGeom.right ());
392 break;
393 case Qt::TopToolBarArea:
394 SetStrut (wid,
395 0, 0, winGeom.height (), 0,
396 0, 0,
397 0, 0,
398 winGeom.left (), winGeom.right (),
399 0, 0);
400 break;
401 case Qt::LeftToolBarArea:
402 SetStrut (wid,
403 winGeom.width (), 0, 0, 0,
404 winGeom.top (), winGeom.bottom (),
405 0, 0,
406 0, 0,
407 0, 0);
408 break;
409 case Qt::RightToolBarArea:
410 SetStrut (wid,
411 0, winGeom.width (), 0, 0,
412 0, 0,
413 winGeom.top (), winGeom.bottom (),
414 0, 0,
415 0, 0);
416 break;
417 default:
418 qWarning () << Q_FUNC_INFO
419 << "incorrect area passed"
420 << area;
421 break;
422 }
423 }
424
425 void XWrapper::ClearStrut (QWidget *w)
426 {
427 const auto wid = w->effectiveWinId ();
428 XDeleteProperty (Display_, wid, GetAtom ("_NET_WM_STRUT"));
429 XDeleteProperty (Display_, wid, GetAtom ("_NET_WM_STRUT_PARTIAL"));
430 }
431
433 ulong left, ulong right, ulong top, ulong bottom,
434 ulong leftStartY, ulong leftEndY,
435 ulong rightStartY, ulong rightEndY,
436 ulong topStartX, ulong topEndX,
437 ulong bottomStartX, ulong bottomEndX)
438 {
439 ulong struts [12] =
440 {
441 left,
442 right,
443 top,
444 bottom,
445
446 leftStartY,
447 leftEndY,
448 rightStartY,
449 rightEndY,
450
451 topStartX,
452 topEndX,
453 bottomStartX,
454 bottomEndX
455 };
456
457 XChangeProperty (Display_, wid, GetAtom ("_NET_WM_STRUT_PARTIAL"),
458 XA_CARDINAL, 32, PropModeReplace, reinterpret_cast<uchar*> (struts), 12);
459
460 XChangeProperty (Display_, wid, GetAtom ("_NET_WM_STRUT"),
461 XA_CARDINAL, 32, PropModeReplace, reinterpret_cast<uchar*> (struts), 4);
462 }
463
465 {
466 SendMessage (wid, GetAtom ("_NET_ACTIVE_WINDOW"), SourcePager);
467 }
468
470 {
471 SendMessage (wid, GetAtom ("WM_CHANGE_STATE"), IconicState);
472 }
473
475 {
476 SendMessage (wid, GetAtom ("_NET_WM_STATE"), StateAdd,
477 GetAtom ("_NET_WM_STATE_MAXIMIZED_VERT"),
478 GetAtom ("_NET_WM_STATE_MAXIMIZED_HORZ"),
480 }
481
483 {
484 SendMessage (wid, GetAtom ("_NET_WM_STATE"), StateRemove,
485 GetAtom ("_NET_WM_STATE_MAXIMIZED_VERT"),
486 GetAtom ("_NET_WM_STATE_MAXIMIZED_HORZ"),
488 }
489
490 void XWrapper::ResizeWindow (Window wid, int width, int height)
491 {
492 XResizeWindow (Display_, wid, width, height);
493 }
494
496 {
497 SendMessage (wid, GetAtom ("_NET_WM_STATE"),
498 StateAdd, GetAtom ("_NET_WM_STATE_SHADED"), 0, SourcePager);
499 }
500
502 {
503 SendMessage (wid, GetAtom ("_NET_WM_STATE"),
504 StateRemove, GetAtom ("_NET_WM_STATE_SHADED"), 0, SourcePager);
505 }
506
508 {
509 const auto top = layer == Layer::Top ? StateAdd : StateRemove;
510 const auto bottom = layer == Layer::Bottom ? StateAdd : StateRemove;
511
512 SendMessage (wid, GetAtom ("_NET_WM_STATE"), top,
513 GetAtom ("_NET_WM_STATE_ABOVE"), 0, SourcePager);
514
515 SendMessage (wid, GetAtom ("_NET_WM_STATE"), bottom,
516 GetAtom ("_NET_WM_STATE_BELOW"), 0, SourcePager);
517 }
518
520 {
521 SendMessage (wid, GetAtom ("_NET_CLOSE_WINDOW"), 0, SourcePager);
522 }
523
524 template<typename T>
525 void XWrapper::HandlePropNotify (T ev)
526 {
527 if (ev->state == XCB_PROPERTY_DELETE)
528 return;
529
530 const auto wid = ev->window;
531
532 if (wid == AppWin_)
533 {
534 if (ev->atom == GetAtom ("_NET_CLIENT_LIST"))
535 emit windowListChanged ();
536 else if (ev->atom == GetAtom ("_NET_ACTIVE_WINDOW"))
537 emit activeWindowChanged ();
538 else if (ev->atom == GetAtom ("_NET_CURRENT_DESKTOP"))
539 emit desktopChanged ();
540 }
541 else
542 {
543 if (ev->atom == GetAtom ("_NET_WM_VISIBLE_NAME") ||
544 ev->atom == GetAtom ("WM_NAME"))
545 emit windowNameChanged (wid);
546 else if (ev->atom == GetAtom ("_NET_WM_ICON"))
547 emit windowIconChanged (wid);
548 else if (ev->atom == GetAtom ("_NET_WM_DESKTOP"))
549 emit windowDesktopChanged (wid);
550 else if (ev->atom == GetAtom ("_NET_WM_STATE"))
551 emit windowStateChanged (wid);
552 else if (ev->atom == GetAtom ("_NET_WM_ALLOWED_ACTIONS"))
553 emit windowActionsChanged (wid);
554 }
555 }
556
557 Window XWrapper::GetActiveWindow ()
558 {
559 ulong length = 0;
560 Guarded<ulong> data;
561
562 if (!GetRootWinProp (GetAtom ("_NET_ACTIVE_WINDOW"), &length, data.GetAs<uchar**> (), XA_WINDOW))
563 return 0;
564
565 if (!length)
566 return 0;
567
568 return data [0];
569 }
570
572 {
573 ulong length = 0;
574 Guarded<ulong> data;
575
576 if (GetRootWinProp (GetAtom ("_NET_NUMBER_OF_DESKTOPS"), &length, data.GetAs<uchar**> (), XA_CARDINAL))
577 return length > 0 ? data [0] : -1;
578
579 return -1;
580 }
581
583 {
584 ulong length = 0;
585 Guarded<ulong> data;
586
587 if (GetRootWinProp (GetAtom ("_NET_CURRENT_DESKTOP"), &length, data.GetAs<uchar**> (), XA_CARDINAL))
588 return length > 0 ? data [0] : -1;
589
590 return -1;
591 }
592
594 {
595 SendMessage (AppWin_, GetAtom ("_NET_CURRENT_DESKTOP"), desktop);
596 }
597
599 {
600 ulong length = 0;
601 Guarded<uchar> data;
602
603 if (!GetRootWinProp (GetAtom ("_NET_DESKTOP_NAMES"),
604 &length, data.GetAs<uchar**> (), GetAtom ("UTF8_STRING")))
605 return {};
606
607 if (!data)
608 return {};
609
610 QStringList result;
611 for (char *pos = data.GetAs<char*> (false), *end = data.GetAs<char*> (false) + length; pos < end; )
612 {
613 const auto& str = QString::fromUtf8 (pos);
614 result << str;
615 pos += str.toUtf8 ().size () + 1;
616 }
617 return result;
618 }
619
620 QString XWrapper::GetDesktopName (int desktop, const QString& def)
621 {
622 return GetDesktopNames ().value (desktop, def);
623 }
624
626 {
627 ulong length = 0;
628 Guarded<ulong> data;
629 if (GetWinProp (wid, GetAtom ("_NET_WM_DESKTOP"), &length, data.GetAs<uchar**> (), XA_CARDINAL) && length)
630 return data [0];
631
632 if (GetWinProp (wid, GetAtom ("_WIN_WORKSPACE"), &length, data.GetAs<uchar**> (), XA_CARDINAL) && length)
633 return data [0];
634
635 return -1;
636 }
637
639 {
640 unsigned long data = num;
641 XChangeProperty (Display_,
642 wid,
643 GetAtom ("_NET_WM_DESKTOP"),
644 XA_CARDINAL,
645 32,
646 PropModeReplace,
647 reinterpret_cast<unsigned char*> (&data),
648 1);
649 }
650
651 QRect XWrapper::GetAvailableGeometry (QScreen& screen)
652 {
653 auto available = screen.geometry ();
654 const auto deskGeom = screen.virtualGeometry ();
655
656 for (const auto wid : GetWindows ())
657 {
658 ulong length = 0;
659 Guarded<ulong> struts;
660 const auto status = GetWinProp (wid, GetAtom ("_NET_WM_STRUT_PARTIAL"),
661 &length, struts.GetAs<uchar**> (), XA_CARDINAL);
662 if (!status || length != 12)
663 continue;
664
665 const QRect left
666 {
667 static_cast<int> (deskGeom.x ()),
668 static_cast<int> (deskGeom.y () + struts [4]),
669 static_cast<int> (struts [0]),
670 static_cast<int> (struts [5] - struts [4])
671 };
672 if (available.intersects (left))
673 available.setX (left.width ());
674
675 const QRect right
676 {
677 static_cast<int> (deskGeom.x () + deskGeom.width () - struts [1]),
678 static_cast<int> (deskGeom.y () + struts [6]),
679 static_cast<int> (struts [1]),
680 static_cast<int> (struts [7] - struts [6])
681 };
682 if (available.intersects (right))
683 available.setWidth (right.x () - available.x ());
684
685 const QRect top
686 {
687 static_cast<int> (deskGeom.x () + struts [8]),
688 static_cast<int> (deskGeom.y ()),
689 static_cast<int> (struts [9] - struts [8]),
690 static_cast<int> (struts [2])
691 };
692 if (available.intersects (top))
693 available.setY (top.height ());
694
695 const QRect bottom
696 {
697 static_cast<int> (deskGeom.x () + struts [10]),
698 static_cast<int> (deskGeom.y () + deskGeom.height () - struts [3]),
699 static_cast<int> (struts [11] - struts [10]),
700 static_cast<int> (struts [3])
701 };
702 if (available.intersects (bottom))
703 available.setHeight (bottom.y () - available.y ());
704 }
705
706 return available;
707 }
708
709 QRect XWrapper::GetAvailableGeometry (QWidget *widget)
710 {
711 return GetAvailableGeometry (*widget->screen ());
712 }
713
714 Atom XWrapper::GetAtom (std::string_view name)
715 {
716 const auto pos = Atoms_.find (AsByteArray (name));
717 if (pos != Atoms_.end ())
718 return *pos;
719
720 auto atom = XInternAtom (Display_, name.data (), false);
721 Atoms_ [ToByteArray (name)] = atom;
722 return atom;
723 }
724
725 bool XWrapper::GetWinProp (Window win, Atom property,
726 ulong *length, unsigned char **result, Atom req) const
727 {
728 int fmt = 0;
729 ulong type = 0, rest = 0;
730 return XGetWindowProperty (Display_, win,
731 property, 0, 1024, false, req, &type,
732 &fmt, length, &rest, result) == Success;
733 }
734
735 bool XWrapper::GetRootWinProp (Atom property,
736 ulong *length, uchar **result, Atom req) const
737 {
738 return GetWinProp (AppWin_, property, length, result, req);
739 }
740
741 QList<Atom> XWrapper::GetWindowType (Window wid)
742 {
743 QList<Atom> result;
744
745 ulong length = 0;
746 ulong *data = nullptr;
747
748 if (!GetWinProp (wid, GetAtom ("_NET_WM_WINDOW_TYPE"),
749 &length, reinterpret_cast<uchar**> (&data)))
750 return result;
751
752 for (ulong i = 0; i < length; ++i)
753 result << data [i];
754
755 XFree (data);
756 return result;
757 }
758
759 bool XWrapper::SendMessage (Window wid, Atom atom, ulong d0, ulong d1, ulong d2, ulong d3, ulong d4)
760 {
761 XEvent msg;
762 msg.xclient.window = wid;
763 msg.xclient.type = ClientMessage;
764 msg.xclient.message_type = atom;
765 msg.xclient.send_event = true;
766 msg.xclient.display = Display_;
767 msg.xclient.format = 32;
768 msg.xclient.data.l [0] = d0;
769 msg.xclient.data.l [1] = d1;
770 msg.xclient.data.l [2] = d2;
771 msg.xclient.data.l [3] = d3;
772 msg.xclient.data.l [4] = d4;
773
774 auto flags = SubstructureRedirectMask | SubstructureNotifyMask;
775 return XSendEvent (Display_, AppWin_, false, flags, &msg) == Success;
776 }
777
778 void XWrapper::initialize ()
779 {
780 }
781}
static std::optional< XWrapper & > Instance()
Definition xwrapper.cpp:52
QList< Window > GetWindows()
Definition xwrapper.cpp:175
QRect GetAvailableGeometry(QScreen &)
Definition xwrapper.cpp:651
void activeWindowChanged()
xcb_connection_t * GetConnection() const
Definition xwrapper.cpp:67
QStringList GetDesktopNames()
Definition xwrapper.cpp:598
Window GetActiveApp()
Definition xwrapper.cpp:318
void UnshadeWindow(Window)
Definition xwrapper.cpp:501
void windowIconChanged(ulong)
bool ShouldShow(Window)
Definition xwrapper.cpp:339
Window GetRootWindow() const
Definition xwrapper.cpp:77
void MinimizeWindow(Window)
Definition xwrapper.cpp:469
XWrapper(xcb_connection_t *, Display *, PrivateCtor)
Definition xwrapper.cpp:35
QString GetDesktopName(int, const QString &=QString())
Definition xwrapper.cpp:620
void windowNameChanged(ulong)
void UnmaximizeWindow(Window)
Definition xwrapper.cpp:482
QIcon GetWindowIcon(Window)
Definition xwrapper.cpp:224
void windowDesktopChanged(ulong)
void ResizeWindow(Window, int, int)
Definition xwrapper.cpp:490
void windowActionsChanged(ulong)
void MaximizeWindow(Window)
Definition xwrapper.cpp:474
void RaiseWindow(Window)
Definition xwrapper.cpp:464
bool IsLCWindow(Window)
Definition xwrapper.cpp:331
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override
Definition xwrapper.cpp:82
AllowedActionFlags GetWindowActions(Window)
Definition xwrapper.cpp:296
void Subscribe(Window)
Definition xwrapper.cpp:369
int GetWindowDesktop(Window)
Definition xwrapper.cpp:625
void MoveWindowTo(Window, Layer)
Definition xwrapper.cpp:507
void SetStrut(QWidget *, Qt::ToolBarArea)
Definition xwrapper.cpp:377
void windowStateChanged(ulong)
void SetCurrentDesktop(int)
Definition xwrapper.cpp:593
WinStateFlags GetWindowState(Window)
Definition xwrapper.cpp:274
void ClearStrut(QWidget *)
Definition xwrapper.cpp:425
Atom GetAtom(std::string_view str)
Returns the atom denoting the given string.
Definition xwrapper.cpp:714
void CloseWindow(Window)
Definition xwrapper.cpp:519
QString GetWindowTitle(Window)
Definition xwrapper.cpp:187
Display * GetDisplay() const
Definition xwrapper.cpp:72
void ShadeWindow(Window)
Definition xwrapper.cpp:495
void MoveWindowToDesktop(Window, int)
Definition xwrapper.cpp:638
constexpr decltype(auto) Get(const Seq &seq)
Definition oral.h:91
@ Attention
Definition winflags.h:29
@ MaximizedVert
Definition winflags.h:20
@ MaximizedHorz
Definition winflags.h:21
@ OnBottom
Definition winflags.h:28
@ Fullscreen
Definition winflags.h:26
@ SkipTaskbar
Definition winflags.h:23
@ SkipPager
Definition winflags.h:24
std::string_view AsStringView(const QByteArray &arr) noexcept
Create a std::string_view referring the data within a QByteArray.
Definition qtutil.h:114
const int StateRemove
Definition xwrapper.cpp:32
QByteArray ToByteArray() noexcept
Definition ctstring.h:151
QByteArray AsByteArray(std::string_view view) noexcept
Convert the view into a QByteArray without copying.
Definition qtutil.h:89
const int SourcePager
Definition xwrapper.cpp:30
const int StateAdd
Definition xwrapper.cpp:33
@ MaximizeVert
Definition winflags.h:43
@ MoveToTop
Definition winflags.h:47
@ Minimize
Definition winflags.h:39
@ MaximizeHorz
Definition winflags.h:42
@ MoveToBottom
Definition winflags.h:48
@ ShowFullscreen
Definition winflags.h:44
@ ChangeDesktop
Definition winflags.h:45
union _XEvent XEvent
Definition xwrapper.h:30
struct _XDisplay Display
Definition xwrapper.h:27
unsigned long Window
Definition xwrapper.h:28