LeechCraft  0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
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 
27 namespace 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 
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 
272  WinStateFlags XWrapper::GetWindowState (Window wid)
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"),
477  SourcePager);
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"),
485  SourcePager);
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 
591  void XWrapper::SetCurrentDesktop (int desktop)
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 }
const int StateAdd
Definition: xwrapper.cpp:32
constexpr detail::AggregateType< detail::AggregateFunction::Count, Ptr > count
Definition: oral.h:1104
void windowIconChanged(ulong)
const int StateRemove
Definition: xwrapper.cpp:31
void SetCurrentDesktop(int)
Definition: xwrapper.cpp:591
void SetStrut(QWidget *, Qt::ToolBarArea)
Definition: xwrapper.cpp:375
const int SourcePager
Definition: xwrapper.cpp:29
QByteArray ToByteArray() noexcept
Definition: ctstring.h:146
constexpr detail::AggregateType< detail::AggregateFunction::Max, Ptr > max
Definition: oral.h:1110
QRect GetAvailableGeometry(QScreen &)
Definition: xwrapper.cpp:649
void swap(FDGuard &g1, FDGuard &g2)
Definition: fdguard.cpp:51
std::string_view AsStringView(const QByteArray &arr) noexcept
Create a std::string_view referring the data within a QByteArray.
Definition: qtutil.h:114
QList< Window > GetWindows()
Definition: xwrapper.cpp:173
void activeWindowChanged()
void MoveWindowTo(Window, Layer)
Definition: xwrapper.cpp:505
QStringList GetDesktopNames()
Definition: xwrapper.cpp:596
QString GetWindowTitle(Window)
Definition: xwrapper.cpp:185
void RaiseWindow(Window)
Definition: xwrapper.cpp:462
void ShadeWindow(Window)
Definition: xwrapper.cpp:493
void ResizeWindow(Window, int, int)
Definition: xwrapper.cpp:488
bool ShouldShow(Window)
Definition: xwrapper.cpp:337
Window GetActiveApp()
Definition: xwrapper.cpp:316
xcb_connection_t * GetConnection() const
Definition: xwrapper.cpp:65
void windowActionsChanged(ulong)
WinStateFlags GetWindowState(Window)
Definition: xwrapper.cpp:272
struct _XDisplay Display
Definition: xwrapper.h:26
void MaximizeWindow(Window)
Definition: xwrapper.cpp:472
int GetWindowDesktop(Window)
Definition: xwrapper.cpp:623
No type (item doesn&#39;t correspond to a radio station).
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override
Definition: xwrapper.cpp:80
QIcon GetWindowIcon(Window)
Definition: xwrapper.cpp:222
void windowNameChanged(ulong)
Atom GetAtom(std::string_view str)
Returns the atom denoting the given string.
Definition: xwrapper.cpp:712
void UnmaximizeWindow(Window)
Definition: xwrapper.cpp:480
unsigned long Window
Definition: xwrapper.h:27
Window GetRootWindow() const
Definition: xwrapper.cpp:75
void ClearStrut(QWidget *)
Definition: xwrapper.cpp:423
QByteArray AsByteArray(std::string_view view) noexcept
Convert the view into a QByteArray without copying.
Definition: qtutil.h:89
decltype(auto) constexpr Get(const Seq &seq)
Definition: oral.h:91
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:68
void CloseWindow(Window)
Definition: xwrapper.cpp:517
QString GetDesktopName(int, const QString &=QString())
Definition: xwrapper.cpp:618
void MoveWindowToDesktop(Window, int)
Definition: xwrapper.cpp:636
Display * GetDisplay() const
Definition: xwrapper.cpp:70
AllowedActionFlags GetWindowActions(Window)
Definition: xwrapper.cpp:294
void UnshadeWindow(Window)
Definition: xwrapper.cpp:499
void Subscribe(Window)
Definition: xwrapper.cpp:367
void windowDesktopChanged(ulong)
bool IsLCWindow(Window)
Definition: xwrapper.cpp:329
void MinimizeWindow(Window)
Definition: xwrapper.cpp:467
static XWrapper & Instance()
Definition: xwrapper.cpp:59
void windowStateChanged(ulong)
union _XEvent XEvent
Definition: xwrapper.h:29