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