KWindowSystem

platforms/xcb/kwindowsystem.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 1999 Matthias Ettrich <[email protected]>
4  SPDX-FileCopyrightText: 2007 Lubos Lunak <[email protected]>
5  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9 
10 #include "kwindowsystem.h"
11 #include "kwindowsystem_p_x11.h"
12 
13 // clang-format off
14 #include <kxerrorhandler_p.h>
15 #include <fixx11h.h>
16 #include <kxutils_p.h>
17 // clang-format on
18 
19 #include <QGuiApplication>
20 #include <QIcon>
21 #include <QMetaMethod>
22 #include <QScreen>
23 #include <QWindow>
24 #include <QX11Info>
25 
26 #include <X11/Xatom.h>
27 #include <X11/Xutil.h>
28 #include <xcb/xcb.h>
29 #include <xcb/xfixes.h>
30 
31 #include <config-kwindowsystem.h>
32 
33 #if KWINDOWSYSTEM_HAVE_XFIXES
34 #include <X11/extensions/Xfixes.h>
35 #endif
36 
37 static Atom net_wm_cm;
38 static void create_atoms();
39 
40 static inline const QRect &displayGeometry()
41 {
42  static QRect displayGeometry;
43  static bool isDirty = true;
44 
45  if (isDirty) {
46  static QList<QMetaObject::Connection> connections;
47  auto dirtify = [&] {
48  isDirty = true;
49  for (const QMetaObject::Connection &con : std::as_const(connections)) {
51  }
52  connections.clear();
53  };
54 
57  const QList<QScreen *> screenList = QGuiApplication::screens();
58  QRegion region;
59  for (int i = 0; i < screenList.count(); ++i) {
60  const QScreen *screen = screenList.at(i);
61  connections << QObject::connect(screen, &QScreen::geometryChanged, dirtify);
62  const QRect geometry = screen->geometry();
63  const qreal dpr = screen->devicePixelRatio();
64  region += QRect(geometry.topLeft(), geometry.size() * dpr);
65  }
66  displayGeometry = region.boundingRect();
67  isDirty = false;
68  }
69 
70  return displayGeometry;
71 }
72 
73 static inline int displayWidth()
74 {
75  return displayGeometry().width();
76 }
77 
78 static inline int displayHeight()
79 {
80  return displayGeometry().height();
81 }
82 
83 // clang-format off
84 static const NET::Properties windowsProperties = NET::ClientList | NET::ClientListStacking |
85  NET::Supported |
86  NET::NumberOfDesktops |
87  NET::DesktopGeometry |
88  NET::DesktopViewport |
89  NET::CurrentDesktop |
90  NET::DesktopNames |
91  NET::ActiveWindow |
92  NET::WorkArea;
93 static const NET::Properties2 windowsProperties2 = NET::WM2ShowingDesktop;
94 
95 // ClientList and ClientListStacking is not per-window information, but a desktop information,
96 // so track it even with only INFO_BASIC
97 static const NET::Properties desktopProperties = NET::ClientList | NET::ClientListStacking |
98  NET::Supported |
99  NET::NumberOfDesktops |
100  NET::DesktopGeometry |
101  NET::DesktopViewport |
102  NET::CurrentDesktop |
103  NET::DesktopNames |
104  NET::ActiveWindow |
105  NET::WorkArea;
106 static const NET::Properties2 desktopProperties2 = NET::WM2ShowingDesktop;
107 // clang-format on
108 
109 MainThreadInstantiator::MainThreadInstantiator(KWindowSystemPrivateX11::FilterInfo _what)
110  : QObject()
111  , m_what(_what)
112 {
113 }
114 
115 NETEventFilter *MainThreadInstantiator::createNETEventFilter()
116 {
117  return new NETEventFilter(m_what);
118 }
119 
120 NETEventFilter::NETEventFilter(KWindowSystemPrivateX11::FilterInfo _what)
121  : NETRootInfo(QX11Info::connection(),
122  _what >= KWindowSystemPrivateX11::INFO_WINDOWS ? windowsProperties : desktopProperties,
123  _what >= KWindowSystemPrivateX11::INFO_WINDOWS ? windowsProperties2 : desktopProperties2,
124  QX11Info::appScreen(),
125  false)
127  , strutSignalConnected(false)
128  , compositingEnabled(false)
129  , haveXfixes(false)
130  , what(_what)
131  , winId(XCB_WINDOW_NONE)
132  , m_appRootWindow(QX11Info::appRootWindow())
133 {
135 
136 #if KWINDOWSYSTEM_HAVE_XFIXES
137  int errorBase;
138  if ((haveXfixes = XFixesQueryExtension(QX11Info::display(), &xfixesEventBase, &errorBase))) {
139  create_atoms();
140  winId = xcb_generate_id(QX11Info::connection());
141  uint32_t values[] = {true, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
142  xcb_create_window(QX11Info::connection(),
143  XCB_COPY_FROM_PARENT,
144  winId,
145  m_appRootWindow,
146  0,
147  0,
148  1,
149  1,
150  0,
151  XCB_WINDOW_CLASS_INPUT_ONLY,
152  XCB_COPY_FROM_PARENT,
153  XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
154  values);
155  XFixesSelectSelectionInput(QX11Info::display(),
156  winId,
157  net_wm_cm,
158  XFixesSetSelectionOwnerNotifyMask | XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask);
159  compositingEnabled = XGetSelectionOwner(QX11Info::display(), net_wm_cm) != None;
160  }
161 #endif
162 }
163 
164 NETEventFilter::~NETEventFilter()
165 {
166  if (QX11Info::connection() && winId != XCB_WINDOW_NONE) {
167  xcb_destroy_window(QX11Info::connection(), winId);
168  winId = XCB_WINDOW_NONE;
169  }
170 }
171 
172 // not virtual, but it's called directly only from init()
173 void NETEventFilter::activate()
174 {
176  updateStackingOrder();
177 }
178 
179 bool NETEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long int *result)
180 {
181  Q_UNUSED(result)
182  if (eventType != "xcb_generic_event_t") {
183  // only interested in XCB events of course
184  return false;
185  }
186  return nativeEventFilter(reinterpret_cast<xcb_generic_event_t *>(message));
187 }
188 
189 bool NETEventFilter::nativeEventFilter(xcb_generic_event_t *ev)
190 {
192  const uint8_t eventType = ev->response_type & ~0x80;
193 
194  if (eventType == xfixesEventBase + XCB_XFIXES_SELECTION_NOTIFY) {
195  xcb_xfixes_selection_notify_event_t *event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(ev);
196  if (event->window == winId) {
197  bool haveOwner = event->owner != XCB_WINDOW_NONE;
198  if (compositingEnabled != haveOwner) {
199  compositingEnabled = haveOwner;
200  Q_EMIT s_q->compositingChanged(compositingEnabled);
201  }
202  return true;
203  }
204  // Qt compresses XFixesSelectionNotifyEvents without caring about the actual window
205  // gui/kernel/qapplication_x11.cpp
206  // until that can be assumed fixed, we also react on events on the root (caused by Qts own compositing tracker)
207  if (event->window == m_appRootWindow) {
208  if (event->selection == net_wm_cm) {
209  bool haveOwner = event->owner != XCB_WINDOW_NONE;
210  if (compositingEnabled != haveOwner) {
211  compositingEnabled = haveOwner;
212  Q_EMIT s_q->compositingChanged(compositingEnabled);
213  }
214  // NOTICE this is not our event, we just randomly captured it from Qt -> pass on
215  return false;
216  }
217  }
218  return false;
219  }
220 
221  xcb_window_t eventWindow = XCB_WINDOW_NONE;
222  switch (eventType) {
223  case XCB_CLIENT_MESSAGE:
224  eventWindow = reinterpret_cast<xcb_client_message_event_t *>(ev)->window;
225  break;
226  case XCB_PROPERTY_NOTIFY:
227  eventWindow = reinterpret_cast<xcb_property_notify_event_t *>(ev)->window;
228  break;
229  case XCB_CONFIGURE_NOTIFY:
230  eventWindow = reinterpret_cast<xcb_configure_notify_event_t *>(ev)->window;
231  break;
232  }
233 
234  if (eventWindow == m_appRootWindow) {
235  int old_current_desktop = currentDesktop();
236  xcb_window_t old_active_window = activeWindow();
237  int old_number_of_desktops = numberOfDesktops();
238  bool old_showing_desktop = showingDesktop();
239  NET::Properties props;
240  NET::Properties2 props2;
241  NETRootInfo::event(ev, &props, &props2);
242 
243  if ((props & CurrentDesktop) && currentDesktop() != old_current_desktop) {
245  }
246  if ((props & DesktopViewport) && mapViewport() && currentDesktop() != old_current_desktop) {
248  }
249  if ((props & ActiveWindow) && activeWindow() != old_active_window) {
251  }
252  if (props & DesktopNames) {
254  }
255  if ((props & NumberOfDesktops) && numberOfDesktops() != old_number_of_desktops) {
257  }
258  if ((props & DesktopGeometry) && mapViewport() && numberOfDesktops() != old_number_of_desktops) {
260  }
261  if (props & WorkArea) {
262  Q_EMIT s_q->workAreaChanged();
263  }
264  if (props & ClientListStacking) {
265  updateStackingOrder();
267  }
268  if ((props2 & WM2ShowingDesktop) && showingDesktop() != old_showing_desktop) {
270  }
271  } else if (windows.contains(eventWindow)) {
272  NETWinInfo ni(QX11Info::connection(), eventWindow, m_appRootWindow, NET::Properties(), NET::Properties2());
273  NET::Properties dirtyProperties;
274  NET::Properties2 dirtyProperties2;
275  ni.event(ev, &dirtyProperties, &dirtyProperties2);
276  if (eventType == XCB_PROPERTY_NOTIFY) {
277  xcb_property_notify_event_t *event = reinterpret_cast<xcb_property_notify_event_t *>(ev);
278  if (event->atom == XCB_ATOM_WM_HINTS) {
279  dirtyProperties |= NET::WMIcon; // support for old icons
280  } else if (event->atom == XCB_ATOM_WM_NAME) {
281  dirtyProperties |= NET::WMName; // support for old name
282  } else if (event->atom == XCB_ATOM_WM_ICON_NAME) {
283  dirtyProperties |= NET::WMIconName; // support for old iconic name
284  }
285  }
286  if (mapViewport() && (dirtyProperties & (NET::WMState | NET::WMGeometry))) {
287  /* geometry change -> possible viewport change
288  * state change -> possible NET::Sticky change
289  */
290  dirtyProperties |= NET::WMDesktop;
291  }
292  if ((dirtyProperties & NET::WMStrut) != 0) {
293  removeStrutWindow(eventWindow);
294  if (!possibleStrutWindows.contains(eventWindow)) {
295  possibleStrutWindows.append(eventWindow);
296  }
297  }
298  if (dirtyProperties || dirtyProperties2) {
299 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 80)
300  Q_EMIT s_q->windowChanged(eventWindow);
301 #endif
302  Q_EMIT s_q->windowChanged(eventWindow, dirtyProperties, dirtyProperties2);
303 
304 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0)
305  unsigned long dirty[2] = {dirtyProperties, dirtyProperties2};
306  Q_EMIT s_q->windowChanged(eventWindow, dirty);
307  Q_EMIT s_q->windowChanged(eventWindow, dirtyProperties);
308 #endif
309  if ((dirtyProperties & NET::WMStrut) != 0) {
310  Q_EMIT s_q->strutChanged();
311  }
312  }
313  }
314 
315  return false;
316 }
317 
318 bool NETEventFilter::removeStrutWindow(WId w)
319 {
320  for (QList<StrutData>::Iterator it = strutWindows.begin(); it != strutWindows.end(); ++it) {
321  if ((*it).window == w) {
322  strutWindows.erase(it);
323  return true;
324  }
325  }
326  return false;
327 }
328 
329 void NETEventFilter::updateStackingOrder()
330 {
332  for (int i = 0; i < clientListStackingCount(); i++) {
333  stackingOrder.append(clientListStacking()[i]);
334  }
335 }
336 
337 void NETEventFilter::addClient(xcb_window_t w)
338 {
340 
341  if ((what >= KWindowSystemPrivateX11::INFO_WINDOWS)) {
342  xcb_connection_t *c = QX11Info::connection();
344  xcb_get_window_attributes_reply(c, xcb_get_window_attributes_unchecked(c, w), nullptr));
345 
346  uint32_t events = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
347  if (!attr.isNull()) {
348  events = events | attr->your_event_mask;
349  }
350  xcb_change_window_attributes(c, w, XCB_CW_EVENT_MASK, &events);
351  }
352 
353  bool emit_strutChanged = false;
354 
355  if (strutSignalConnected) {
356  NETWinInfo info(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMStrut | NET::WMDesktop, NET::Properties2());
357  NETStrut strut = info.strut();
358  if (strut.left || strut.top || strut.right || strut.bottom) {
359  strutWindows.append(StrutData(w, strut, info.desktop()));
360  emit_strutChanged = true;
361  }
362  } else {
363  possibleStrutWindows.append(w);
364  }
365 
366  windows.append(w);
367  Q_EMIT s_q->windowAdded(w);
368  if (emit_strutChanged) {
369  Q_EMIT s_q->strutChanged();
370  }
371 }
372 
373 void NETEventFilter::removeClient(xcb_window_t w)
374 {
376 
377  bool emit_strutChanged = removeStrutWindow(w);
378  if (strutSignalConnected && possibleStrutWindows.contains(w)) {
379  NETWinInfo info(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMStrut, NET::Properties2());
380  NETStrut strut = info.strut();
381  if (strut.left || strut.top || strut.right || strut.bottom) {
382  emit_strutChanged = true;
383  }
384  }
385 
386  possibleStrutWindows.removeAll(w);
387  windows.removeAll(w);
388  Q_EMIT s_q->windowRemoved(w);
389  if (emit_strutChanged) {
390  Q_EMIT s_q->strutChanged();
391  }
392 }
393 
394 bool NETEventFilter::mapViewport()
395 {
396  // compiz claims support even though it doesn't use virtual desktops :(
397  // if( isSupported( NET::DesktopViewport ) && !isSupported( NET::NumberOfDesktops ))
398 
399  // this test is duplicated in KWindowSystem::mapViewport()
400  if (isSupported(NET::DesktopViewport) && numberOfDesktops(true) <= 1
401  && (desktopGeometry().width > displayWidth() || desktopGeometry().height > displayHeight())) {
402  return true;
403  }
404  return false;
405 }
406 
407 static bool atoms_created = false;
408 
409 static Atom _wm_protocols;
410 static Atom _wm_change_state;
411 static Atom kwm_utf8_string;
412 
413 static void create_atoms()
414 {
415  if (!atoms_created) {
416  const int max = 20;
417  Atom *atoms[max];
418  const char *names[max];
419  Atom atoms_return[max];
420  int n = 0;
421 
422  atoms[n] = &_wm_protocols;
423  names[n++] = "WM_PROTOCOLS";
424 
425  atoms[n] = &_wm_change_state;
426  names[n++] = "WM_CHANGE_STATE";
427 
428  atoms[n] = &kwm_utf8_string;
429  names[n++] = "UTF8_STRING";
430 
431  char net_wm_cm_name[100];
432  sprintf(net_wm_cm_name, "_NET_WM_CM_S%d", QX11Info::appScreen());
433  atoms[n] = &net_wm_cm;
434  names[n++] = net_wm_cm_name;
435 
436  // we need a const_cast for the shitty X API
437  XInternAtoms(QX11Info::display(), const_cast<char **>(names), n, false, atoms_return);
438  for (int i = 0; i < n; i++) {
439  *atoms[i] = atoms_return[i];
440  }
441 
442  atoms_created = True;
443  }
444 }
445 
446 // optimalization - create KWindowSystemPrivate only when needed and only for what is needed
447 void KWindowSystemPrivateX11::connectNotify(const QMetaMethod &signal)
448 {
449  FilterInfo what = INFO_BASIC;
451  what = INFO_WINDOWS;
452  } else if (signal == QMetaMethod::fromSignal(&KWindowSystem::strutChanged)) {
453  what = INFO_WINDOWS;
454  } else if (signal == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId, NET::Properties, NET::Properties2)>(&KWindowSystem::windowChanged))) {
455  what = INFO_WINDOWS;
456  }
457 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0)
458  else if (signal == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId, const unsigned long *)>(&KWindowSystem::windowChanged))) {
459  what = INFO_WINDOWS;
460  } else if (signal == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId, uint)>(&KWindowSystem::windowChanged))) {
461  what = INFO_WINDOWS;
462  }
463 #endif
464 
465 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 80)
466  else if (signal == QMetaMethod::fromSignal(static_cast<void (KWindowSystem::*)(WId)>(&KWindowSystem::windowChanged))) {
467  what = INFO_WINDOWS;
468  }
469 #endif
470 
471  init(what);
472  NETEventFilter *const s_d = s_d_func();
473  if (!s_d->strutSignalConnected && signal == QMetaMethod::fromSignal(&KWindowSystem::strutChanged)) {
474  s_d->strutSignalConnected = true;
475  }
476 }
477 
478 // WARNING
479 // you have to call s_d_func() again after calling this function if you want a valid pointer!
480 void KWindowSystemPrivateX11::init(FilterInfo what)
481 {
482  NETEventFilter *const s_d = s_d_func();
483 
484  if (what >= INFO_WINDOWS) {
485  what = INFO_WINDOWS;
486  } else {
487  what = INFO_BASIC;
488  }
489 
490  if (!s_d || s_d->what < what) {
491  const bool wasCompositing = s_d ? s_d->compositingEnabled : false;
492  MainThreadInstantiator instantiator(what);
493  NETEventFilter *filter;
494  if (instantiator.thread() == QCoreApplication::instance()->thread()) {
495  filter = instantiator.createNETEventFilter();
496  } else {
497  // the instantiator is not in the main app thread, which implies
498  // we are being called in a thread that is not the main app thread
499  // so we move the instantiator to the main app thread and invoke
500  // the method with a blocking call
501  instantiator.moveToThread(QCoreApplication::instance()->thread());
502  QMetaObject::invokeMethod(&instantiator, "createNETEventFilter", Qt::BlockingQueuedConnection, Q_RETURN_ARG(NETEventFilter *, filter));
503  }
504  d.reset(filter);
505  d->activate();
506  if (wasCompositing != s_d_func()->compositingEnabled) {
507  Q_EMIT KWindowSystem::self()->compositingChanged(s_d_func()->compositingEnabled);
508  }
509  }
510 }
511 
512 QList<WId> KWindowSystemPrivateX11::windows()
513 {
514  init(INFO_BASIC);
515  return s_d_func()->windows;
516 }
517 
518 QList<WId> KWindowSystemPrivateX11::stackingOrder()
519 {
520  init(INFO_BASIC);
521  return s_d_func()->stackingOrder;
522 }
523 
524 int KWindowSystemPrivateX11::currentDesktop()
525 {
526  if (!QX11Info::connection()) {
527  return 1;
528  }
529 
530  if (mapViewport()) {
531  init(INFO_BASIC);
532  NETEventFilter *const s_d = s_d_func();
533  NETPoint p = s_d->desktopViewport(s_d->currentDesktop(true));
534  return viewportToDesktop(QPoint(p.x, p.y));
535  }
536 
537  NETEventFilter *const s_d = s_d_func();
538  if (s_d) {
539  return s_d->currentDesktop(true);
540  }
541  NETRootInfo info(QX11Info::connection(), NET::CurrentDesktop, NET::Properties2(), QX11Info::appScreen());
542  return info.currentDesktop(true);
543 }
544 
545 int KWindowSystemPrivateX11::numberOfDesktops()
546 {
547  if (!QX11Info::connection()) {
548  return 1;
549  }
550 
551  if (mapViewport()) {
552  init(INFO_BASIC);
553  NETEventFilter *const s_d = s_d_func();
554  NETSize s = s_d->desktopGeometry();
555  return s.width / displayWidth() * s.height / displayHeight();
556  }
557 
558  NETEventFilter *const s_d = s_d_func();
559  if (s_d) {
560  return s_d->numberOfDesktops(true);
561  }
562  NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops, NET::Properties2(), QX11Info::appScreen());
563  return info.numberOfDesktops(true);
564 }
565 
566 void KWindowSystemPrivateX11::setCurrentDesktop(int desktop)
567 {
568  if (mapViewport()) {
569  init(INFO_BASIC);
570  NETEventFilter *const s_d = s_d_func();
571  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::Properties2(), QX11Info::appScreen());
572  QPoint pos = desktopToViewport(desktop, true);
573  NETPoint p;
574  p.x = pos.x();
575  p.y = pos.y();
576  info.setDesktopViewport(s_d->currentDesktop(true), p);
577  return;
578  }
579  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::Properties2(), QX11Info::appScreen());
580  info.setCurrentDesktop(desktop, true);
581 }
582 
583 void KWindowSystemPrivateX11::setOnAllDesktops(WId win, bool b)
584 {
585  if (mapViewport()) {
586  if (b) {
587  setState(win, NET::Sticky);
588  } else {
589  clearState(win, NET::Sticky);
590  }
591  return;
592  }
593  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMDesktop, NET::Properties2());
594  if (b) {
595  info.setDesktop(NETWinInfo::OnAllDesktops, true);
596  } else if (info.desktop(true) == NETWinInfo::OnAllDesktops) {
597  NETRootInfo rinfo(QX11Info::connection(), NET::CurrentDesktop, NET::Properties2(), QX11Info::appScreen());
598  info.setDesktop(rinfo.currentDesktop(true), true);
599  }
600 }
601 
602 void KWindowSystemPrivateX11::setOnDesktop(WId win, int desktop)
603 {
604  if (mapViewport()) {
605  if (desktop == NET::OnAllDesktops) {
606  return setOnAllDesktops(win, true);
607  } else {
608  clearState(win, NET::Sticky);
609  }
610  init(INFO_BASIC);
611  QPoint p = desktopToViewport(desktop, false);
612  Window dummy;
613  int x;
614  int y;
615  unsigned int w;
616  unsigned int h;
617  unsigned int b;
618  unsigned int dp;
619  XGetGeometry(QX11Info::display(), win, &dummy, &x, &y, &w, &h, &b, &dp);
620  // get global position
621  XTranslateCoordinates(QX11Info::display(), win, QX11Info::appRootWindow(), 0, 0, &x, &y, &dummy);
622  x += w / 2; // center
623  y += h / 2;
624  // transform to coordinates on the current "desktop"
625  x = x % displayWidth();
626  y = y % displayHeight();
627  if (x < 0) {
628  x = x + displayWidth();
629  }
630  if (y < 0) {
631  y = y + displayHeight();
632  }
633  x += p.x(); // move to given "desktop"
634  y += p.y();
635  x -= w / 2; // from center back to topleft
636  y -= h / 2;
638  int flags = (NET::FromTool << 12) | (0x03 << 8) | 10; // from tool(?), x/y, static gravity
639  NETEventFilter *const s_d = s_d_func();
640  s_d->moveResizeWindowRequest(win, flags, p.x(), p.y(), w, h);
641  return;
642  }
643  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMDesktop, NET::Properties2());
644  info.setDesktop(desktop, true);
645 }
646 
647 void KWindowSystemPrivateX11::setOnActivities(WId win, const QStringList &activities)
648 {
649  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::Properties(), NET::WM2Activities);
650  info.setActivities(activities.join(QLatin1Char(',')).toLatin1().constData());
651 }
652 
653 WId KWindowSystemPrivateX11::activeWindow()
654 {
655  NETEventFilter *const s_d = s_d_func();
656  if (s_d) {
657  return s_d->activeWindow();
658  }
659  NETRootInfo info(QX11Info::connection(), NET::ActiveWindow, NET::Properties2(), QX11Info::appScreen());
660  return info.activeWindow();
661 }
662 
663 void KWindowSystemPrivateX11::activateWindow(WId win, long time)
664 {
665  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::Properties2(), QX11Info::appScreen());
666  if (time == 0) {
667  time = QX11Info::appUserTime();
668  }
669  info.setActiveWindow(win, NET::FromApplication, time, QGuiApplication::focusWindow() ? QGuiApplication::focusWindow()->winId() : 0);
670 }
671 
672 void KWindowSystemPrivateX11::forceActiveWindow(WId win, long time)
673 {
674  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::Properties2(), QX11Info::appScreen());
675  if (time == 0) {
676  time = QX11Info::appTime();
677  }
678  info.setActiveWindow(win, NET::FromTool, time, 0);
679 }
680 
681 void KWindowSystemPrivateX11::demandAttention(WId win, bool set)
682 {
683  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMState, NET::Properties2());
684  info.setState(set ? NET::DemandsAttention : NET::States(), NET::DemandsAttention);
685 }
686 
687 #if KWINDOWSYSTEM_BUILD_DEPRECATED_SINCE(5, 0)
688 WId KWindowSystemPrivateX11::transientFor(WId win)
689 {
690  KWindowInfo info(win, NET::Properties(), NET::WM2TransientFor);
691  return info.transientFor();
692 }
693 
694 WId KWindowSystemPrivateX11::groupLeader(WId win)
695 {
696  KWindowInfo info(win, NET::Properties(), NET::WM2GroupLeader);
697  return info.groupLeader();
698 }
699 #endif
700 
701 QPixmap KWindowSystemPrivateX11::icon(WId win, int width, int height, bool scale, int flags)
702 {
703  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMIcon, NET::WM2WindowClass | NET::WM2IconPixmap);
704  return iconFromNetWinInfo(width, height, scale, flags, &info);
705 }
706 
707 QPixmap KWindowSystemPrivateX11::iconFromNetWinInfo(int width, int height, bool scale, int flags, NETWinInfo *info)
708 {
709  QPixmap result;
710  if (!info) {
711  return result;
712  }
713  if (flags & KWindowSystem::NETWM) {
714  NETIcon ni = info->icon(width, height);
715  if (ni.data && ni.size.width > 0 && ni.size.height > 0) {
716  QImage img((uchar *)ni.data, (int)ni.size.width, (int)ni.size.height, QImage::Format_ARGB32);
717  if (scale && width > 0 && height > 0 && img.size() != QSize(width, height) && !img.isNull()) {
718  img = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
719  }
720  if (!img.isNull()) {
721  result = QPixmap::fromImage(img);
722  }
723  return result;
724  }
725  }
726 
727  if (flags & KWindowSystem::WMHints) {
728  xcb_pixmap_t p = info->icccmIconPixmap();
729  xcb_pixmap_t p_mask = info->icccmIconPixmapMask();
730 
731  if (p != XCB_PIXMAP_NONE) {
732  QPixmap pm = KXUtils::createPixmapFromHandle(info->xcbConnection(), p, p_mask);
733  if (scale && width > 0 && height > 0 && !pm.isNull() //
734  && (pm.width() != width || pm.height() != height)) {
736  } else {
737  result = pm;
738  }
739  }
740  }
741 
742  // Since width can be any arbitrary size, but the icons cannot,
743  // take the nearest value for best results (ignoring 22 pixel
744  // icons as they don't exist for apps):
745  int iconWidth;
746  if (width < 24) {
747  iconWidth = 16;
748  } else if (width < 40) {
749  iconWidth = 32;
750  } else if (width < 56) {
751  iconWidth = 48;
752  } else if (width < 96) {
753  iconWidth = 64;
754  } else if (width < 192) {
755  iconWidth = 128;
756  } else {
757  iconWidth = 256;
758  }
759 
760  if (flags & KWindowSystem::ClassHint) {
761  // Try to load the icon from the classhint if the app didn't specify
762  // its own:
763  if (result.isNull()) {
764  const QIcon icon = QIcon::fromTheme(QString::fromUtf8(info->windowClassClass()).toLower());
765  const QPixmap pm = icon.isNull() ? QPixmap() : icon.pixmap(iconWidth, iconWidth);
766  if (scale && !pm.isNull()) {
767  result = QPixmap::fromImage(pm.toImage().scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
768  } else {
769  result = pm;
770  }
771  }
772  }
773 
774  if (flags & KWindowSystem::XApp) {
775  // If the icon is still a null pixmap, load the icon for X applications
776  // as a last resort:
777  if (result.isNull()) {
778  const QIcon icon = QIcon::fromTheme(QStringLiteral("xorg"));
779  const QPixmap pm = icon.isNull() ? QPixmap() : icon.pixmap(iconWidth, iconWidth);
780  if (scale && !pm.isNull()) {
782  } else {
783  result = pm;
784  }
785  }
786  }
787  return result;
788 }
789 
790 void KWindowSystemPrivateX11::setIcons(WId win, const QPixmap &icon, const QPixmap &miniIcon)
791 {
792  if (icon.isNull()) {
793  return;
794  }
795  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::Properties(), NET::Properties2());
797  NETIcon ni;
798  ni.size.width = img.size().width();
799  ni.size.height = img.size().height();
800  ni.data = (unsigned char *)img.bits();
801  info.setIcon(ni, true);
802  if (miniIcon.isNull()) {
803  return;
804  }
806  if (img.isNull()) {
807  return;
808  }
809  ni.size.width = img.size().width();
810  ni.size.height = img.size().height();
811  ni.data = (unsigned char *)img.bits();
812  info.setIcon(ni, false);
813 }
814 
815 void KWindowSystemPrivateX11::setType(WId win, NET::WindowType windowType)
816 {
817  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::Properties(), NET::Properties2());
818  info.setWindowType(windowType);
819 }
820 
821 void KWindowSystemPrivateX11::setState(WId win, NET::States state)
822 {
823  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMState, NET::Properties2());
824  info.setState(state, state);
825 }
826 
827 void KWindowSystemPrivateX11::clearState(WId win, NET::States state)
828 {
829  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMState, NET::Properties2());
830  info.setState(NET::States(), state);
831 }
832 
833 // enum values for ICCCM 4.1.2.4 and 4.1.4, defined to not depend on xcb-icccm
834 enum {
835  _ICCCM_WM_STATE_WITHDRAWN = 0,
836  _ICCCM_WM_STATE_NORMAL = 1,
837  _ICCCM_WM_STATE_ICONIC = 3,
838 };
839 
840 void KWindowSystemPrivateX11::minimizeWindow(WId win)
841 {
842  create_atoms();
843  // as described in ICCCM 4.1.4
844  xcb_client_message_event_t ev;
845  memset(&ev, 0, sizeof(ev));
846  ev.response_type = XCB_CLIENT_MESSAGE;
847  ev.window = win;
848  ev.type = _wm_change_state;
849  ev.format = 32;
850  ev.data.data32[0] = _ICCCM_WM_STATE_ICONIC;
851  ev.data.data32[1] = 0;
852  ev.data.data32[2] = 0;
853  ev.data.data32[3] = 0;
854  ev.data.data32[4] = 0;
855  xcb_send_event(QX11Info::connection(),
856  false,
857  QX11Info::appRootWindow(),
858  XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
859  reinterpret_cast<const char *>(&ev));
860 }
861 
862 void KWindowSystemPrivateX11::unminimizeWindow(WId win)
863 {
864  xcb_map_window(QX11Info::connection(), win);
865 }
866 
867 void KWindowSystemPrivateX11::raiseWindow(WId win)
868 {
869  NETRootInfo info(QX11Info::connection(), NET::Supported, NET::Properties2(), QX11Info::appScreen());
870  if (info.isSupported(NET::WM2RestackWindow)) {
871  info.restackRequest(win, NET::FromTool, XCB_WINDOW_NONE, XCB_STACK_MODE_ABOVE, QX11Info::appUserTime());
872  } else {
873  const uint32_t values[] = {XCB_STACK_MODE_ABOVE};
874  xcb_configure_window(QX11Info::connection(), win, XCB_CONFIG_WINDOW_STACK_MODE, values);
875  }
876 }
877 
878 void KWindowSystemPrivateX11::lowerWindow(WId win)
879 {
880  NETRootInfo info(QX11Info::connection(), NET::Supported, NET::Properties2(), QX11Info::appScreen());
881  if (info.isSupported(NET::WM2RestackWindow)) {
882  info.restackRequest(win, NET::FromTool, XCB_WINDOW_NONE, XCB_STACK_MODE_BELOW, QX11Info::appUserTime());
883  } else {
884  const uint32_t values[] = {XCB_STACK_MODE_BELOW};
885  xcb_configure_window(QX11Info::connection(), win, XCB_CONFIG_WINDOW_STACK_MODE, values);
886  }
887 }
888 
889 bool KWindowSystemPrivateX11::compositingActive()
890 {
891  init(INFO_BASIC);
892  if (s_d_func()->haveXfixes) {
893  return s_d_func()->compositingEnabled;
894  } else {
895  create_atoms();
896  return XGetSelectionOwner(QX11Info::display(), net_wm_cm);
897  }
898 }
899 
900 QRect KWindowSystemPrivateX11::workArea(int desktop)
901 {
902  init(INFO_BASIC);
903  int desk = (desktop > 0 && desktop <= (int)s_d_func()->numberOfDesktops()) ? desktop : currentDesktop();
904  if (desk <= 0) {
905  return displayGeometry();
906  }
907 
908  NETRect r = s_d_func()->workArea(desk);
909  if (r.size.width <= 0 || r.size.height <= 0) { // not set
910  return displayGeometry();
911  }
912 
913  return QRect(r.pos.x, r.pos.y, r.size.width, r.size.height);
914 }
915 
916 QRect KWindowSystemPrivateX11::workArea(const QList<WId> &exclude, int desktop)
917 {
918  init(INFO_WINDOWS); // invalidates s_d_func's return value
919  NETEventFilter *const s_d = s_d_func();
920 
921  QRect all = displayGeometry();
922  QRect a = all;
923 
924  if (desktop == -1) {
925  desktop = s_d->currentDesktop();
926  }
927 
929  for (it1 = s_d->windows.constBegin(); it1 != s_d->windows.constEnd(); ++it1) {
930  if (exclude.contains(*it1)) {
931  continue;
932  }
933 
934  // Kicker (very) extensively calls this function, causing hundreds of roundtrips just
935  // to repeatedly find out struts of all windows. Therefore strut values for strut
936  // windows are cached here.
937  NETStrut strut;
938  auto it2 = s_d->strutWindows.begin();
939  for (; it2 != s_d->strutWindows.end(); ++it2) {
940  if ((*it2).window == *it1) {
941  break;
942  }
943  }
944 
945  if (it2 != s_d->strutWindows.end()) {
946  if (!((*it2).desktop == desktop || (*it2).desktop == NETWinInfo::OnAllDesktops)) {
947  continue;
948  }
949 
950  strut = (*it2).strut;
951  } else if (s_d->possibleStrutWindows.contains(*it1)) {
952  NETWinInfo info(QX11Info::connection(), (*it1), QX11Info::appRootWindow(), NET::WMStrut | NET::WMDesktop, NET::Properties2());
953  strut = info.strut();
954  s_d->possibleStrutWindows.removeAll(*it1);
955  s_d->strutWindows.append(NETEventFilter::StrutData(*it1, info.strut(), info.desktop()));
956 
957  if (!(info.desktop() == desktop || info.desktop() == NETWinInfo::OnAllDesktops)) {
958  continue;
959  }
960  } else {
961  continue; // not a strut window
962  }
963 
964  QRect r = all;
965  if (strut.left > 0) {
966  r.setLeft(r.left() + (int)strut.left);
967  }
968  if (strut.top > 0) {
969  r.setTop(r.top() + (int)strut.top);
970  }
971  if (strut.right > 0) {
972  r.setRight(r.right() - (int)strut.right);
973  }
974  if (strut.bottom > 0) {
975  r.setBottom(r.bottom() - (int)strut.bottom);
976  }
977 
978  a = a.intersected(r);
979  }
980  return a;
981 }
982 
983 QString KWindowSystemPrivateX11::desktopName(int desktop)
984 {
985  init(INFO_BASIC);
986  NETEventFilter *const s_d = s_d_func();
987 
988  bool isDesktopSane = (desktop > 0 && desktop <= (int)s_d->numberOfDesktops());
989  const char *name = s_d->desktopName(isDesktopSane ? desktop : currentDesktop());
990 
991  if (name && name[0]) {
992  return QString::fromUtf8(name);
993  }
994 
995  return KWindowSystem::tr("Desktop %1").arg(desktop);
996 }
997 
998 void KWindowSystemPrivateX11::setDesktopName(int desktop, const QString &name)
999 {
1000  NETEventFilter *const s_d = s_d_func();
1001 
1002  if (desktop <= 0 || desktop > (int)numberOfDesktops()) {
1003  desktop = currentDesktop();
1004  }
1005 
1006  if (s_d) {
1007  s_d->setDesktopName(desktop, name.toUtf8().constData());
1008  return;
1009  }
1010 
1011  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::Properties2(), QX11Info::appScreen());
1012  info.setDesktopName(desktop, name.toUtf8().constData());
1013 }
1014 
1015 bool KWindowSystemPrivateX11::showingDesktop()
1016 {
1017  init(INFO_BASIC);
1018  return s_d_func()->showingDesktop();
1019 }
1020 
1021 void KWindowSystemPrivateX11::setShowingDesktop(bool showing)
1022 {
1023  NETRootInfo info(QX11Info::connection(), NET::Properties(), NET::WM2ShowingDesktop, QX11Info::appScreen());
1024  info.setShowingDesktop(showing);
1025 }
1026 
1027 void KWindowSystemPrivateX11::setUserTime(WId win, long time)
1028 {
1029  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::Properties(), NET::Properties2());
1030  info.setUserTime(time);
1031 }
1032 
1033 void KWindowSystemPrivateX11::setExtendedStrut(WId win,
1034  int left_width,
1035  int left_start,
1036  int left_end,
1037  int right_width,
1038  int right_start,
1039  int right_end,
1040  int top_width,
1041  int top_start,
1042  int top_end,
1043  int bottom_width,
1044  int bottom_start,
1045  int bottom_end)
1046 {
1047  NETWinInfo info(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::Properties(), NET::Properties2());
1048  NETExtendedStrut strut;
1049  strut.left_width = left_width;
1050  strut.right_width = right_width;
1051  strut.top_width = top_width;
1052  strut.bottom_width = bottom_width;
1053  strut.left_start = left_start;
1054  strut.left_end = left_end;
1055  strut.right_start = right_start;
1056  strut.right_end = right_end;
1057  strut.top_start = top_start;
1058  strut.top_end = top_end;
1059  strut.bottom_start = bottom_start;
1060  strut.bottom_end = bottom_end;
1061  info.setExtendedStrut(strut);
1062  NETStrut oldstrut;
1063  oldstrut.left = left_width;
1064  oldstrut.right = right_width;
1065  oldstrut.top = top_width;
1066  oldstrut.bottom = bottom_width;
1067  info.setStrut(oldstrut);
1068 }
1069 
1070 void KWindowSystemPrivateX11::setStrut(WId win, int left, int right, int top, int bottom)
1071 {
1072  int w = displayWidth();
1073  int h = displayHeight();
1074  setExtendedStrut(win, left, 0, left != 0 ? w : 0, right, 0, right != 0 ? w : 0, top, 0, top != 0 ? h : 0, bottom, 0, bottom != 0 ? h : 0);
1075 }
1076 
1077 bool KWindowSystemPrivateX11::icccmCompliantMappingState()
1078 {
1079  static enum { noidea, yes, no } wm_is_1_2_compliant = noidea;
1080  if (wm_is_1_2_compliant == noidea) {
1081  NETRootInfo info(QX11Info::connection(), NET::Supported, NET::Properties2(), QX11Info::appScreen());
1082  wm_is_1_2_compliant = info.isSupported(NET::Hidden) ? yes : no;
1083  }
1084  return wm_is_1_2_compliant == yes;
1085 }
1086 
1087 bool KWindowSystemPrivateX11::allowedActionsSupported()
1088 {
1089  static enum { noidea, yes, no } wm_supports_allowed_actions = noidea;
1090  if (wm_supports_allowed_actions == noidea) {
1091  NETRootInfo info(QX11Info::connection(), NET::Supported, NET::Properties2(), QX11Info::appScreen());
1092  wm_supports_allowed_actions = info.isSupported(NET::WM2AllowedActions) ? yes : no;
1093  }
1094  return wm_supports_allowed_actions == yes;
1095 }
1096 
1097 QString KWindowSystemPrivateX11::readNameProperty(WId win, unsigned long atom)
1098 {
1099  XTextProperty tp;
1100  char **text = nullptr;
1101  int count;
1102  QString result;
1103  if (XGetTextProperty(QX11Info::display(), win, &tp, atom) != 0 && tp.value != nullptr) {
1104  create_atoms();
1105 
1106  if (tp.encoding == kwm_utf8_string) {
1107  result = QString::fromUtf8((const char *)tp.value);
1108  } else if (XmbTextPropertyToTextList(QX11Info::display(), &tp, &text, &count) == Success && text != nullptr && count > 0) {
1109  result = QString::fromLocal8Bit(text[0]);
1110  } else if (tp.encoding == XA_STRING) {
1111  result = QString::fromLocal8Bit((const char *)tp.value);
1112  }
1113  if (text != nullptr) {
1114  XFreeStringList(text);
1115  }
1116  XFree(tp.value);
1117  }
1118  return result;
1119 }
1120 
1121 void KWindowSystemPrivateX11::allowExternalProcessWindowActivation(int pid)
1122 {
1123  // Normally supported by X11, but may depend on some window managers ?
1124  Q_UNUSED(pid)
1125 }
1126 
1127 void KWindowSystemPrivateX11::setBlockingCompositing(WId window, bool active)
1128 {
1129  NETWinInfo info(QX11Info::connection(), window, QX11Info::appRootWindow(), NET::Properties(), NET::Properties2());
1130  info.setBlockingCompositing(active);
1131 }
1132 
1133 bool KWindowSystemPrivateX11::mapViewport()
1134 {
1135  NETEventFilter *const s_d = s_d_func();
1136  if (s_d) {
1137  return s_d->mapViewport();
1138  }
1139  // avoid creating KWindowSystemPrivate
1140  NETRootInfo infos(QX11Info::connection(), NET::Supported, NET::Properties2(), QX11Info::appScreen());
1141  if (!infos.isSupported(NET::DesktopViewport)) {
1142  return false;
1143  }
1144  NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops | NET::CurrentDesktop | NET::DesktopGeometry, NET::Properties2(), QX11Info::appScreen());
1145  if (info.numberOfDesktops(true) <= 1 && (info.desktopGeometry().width > displayWidth() || info.desktopGeometry().height > displayHeight())) {
1146  return true;
1147  }
1148  return false;
1149 }
1150 
1151 int KWindowSystemPrivateX11::viewportToDesktop(const QPoint &p)
1152 {
1153  init(INFO_BASIC);
1154  NETEventFilter *const s_d = s_d_func();
1155  NETSize s = s_d->desktopGeometry();
1156  QSize vs(displayWidth(), displayHeight());
1157  int xs = s.width / vs.width();
1158  int x = p.x() < 0 ? 0 : p.x() >= s.width ? xs - 1 : p.x() / vs.width();
1159  int ys = s.height / vs.height();
1160  int y = p.y() < 0 ? 0 : p.y() >= s.height ? ys - 1 : p.y() / vs.height();
1161  return y * xs + x + 1;
1162 }
1163 
1164 int KWindowSystemPrivateX11::viewportWindowToDesktop(const QRect &r)
1165 {
1166  init(INFO_BASIC);
1167  NETEventFilter *const s_d = s_d_func();
1168  QPoint p = r.center();
1169  // make absolute
1170  p = QPoint(p.x() + s_d->desktopViewport(s_d->currentDesktop(true)).x, p.y() + s_d->desktopViewport(s_d->currentDesktop(true)).y);
1171  NETSize s = s_d->desktopGeometry();
1172  QSize vs(displayWidth(), displayHeight());
1173  int xs = s.width / vs.width();
1174  int x = p.x() < 0 ? 0 : p.x() >= s.width ? xs - 1 : p.x() / vs.width();
1175  int ys = s.height / vs.height();
1176  int y = p.y() < 0 ? 0 : p.y() >= s.height ? ys - 1 : p.y() / vs.height();
1177  return y * xs + x + 1;
1178 }
1179 
1180 QPoint KWindowSystemPrivateX11::desktopToViewport(int desktop, bool absolute)
1181 {
1182  init(INFO_BASIC);
1183  NETEventFilter *const s_d = s_d_func();
1184  NETSize s = s_d->desktopGeometry();
1185  QSize vs(displayWidth(), displayHeight());
1186  int xs = s.width / vs.width();
1187  int ys = s.height / vs.height();
1188  if (desktop <= 0 || desktop > xs * ys) {
1189  return QPoint(0, 0);
1190  }
1191  --desktop;
1192  QPoint ret(vs.width() * (desktop % xs), vs.height() * (desktop / xs));
1193  if (!absolute) {
1194  ret = QPoint(ret.x() - s_d->desktopViewport(s_d->currentDesktop(true)).x, ret.y() - s_d->desktopViewport(s_d->currentDesktop(true)).y);
1195  if (ret.x() >= s.width) {
1196  ret.setX(ret.x() - s.width);
1197  }
1198  if (ret.x() < 0) {
1199  ret.setX(ret.x() + s.width);
1200  }
1201  if (ret.y() >= s.height) {
1202  ret.setY(ret.y() - s.height);
1203  }
1204  if (ret.y() < 0) {
1205  ret.setY(ret.y() + s.height);
1206  }
1207  }
1208  return ret;
1209 }
1210 
1211 QPoint KWindowSystemPrivateX11::constrainViewportRelativePosition(const QPoint &pos)
1212 {
1213  init(INFO_BASIC);
1214  NETEventFilter *const s_d = s_d_func();
1215  NETSize s = s_d->desktopGeometry();
1216  NETPoint c = s_d->desktopViewport(s_d->currentDesktop(true));
1217  int x = (pos.x() + c.x) % s.width;
1218  int y = (pos.y() + c.y) % s.height;
1219  if (x < 0) {
1220  x += s.width;
1221  }
1222  if (y < 0) {
1223  y += s.height;
1224  }
1225  return QPoint(x - c.x, y - c.y);
1226 }
1227 
1228 #include "moc_kwindowsystem_p_x11.cpp"
Simple icon class for NET classes.
Definition: netwm_def.h:147
void clear()
void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2)
The window changed.
void setBottom(int y)
QImage convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags) const &const
QSize size() const const
void desktopNamesChanged()
Desktops have been renamed.
int bottom
Bottom border of the strut.
Definition: netwm_def.h:262
int width() const const
void setWindowType(WindowType type)
Sets the window type for this client (see the NET base class documentation for a description of the v...
Definition: netwm.cpp:3022
QString name(const QVariant &location)
int width() const const
int bottom_width
Bottom border of the strut, width and range.
Definition: netwm_def.h:218
void compositingChanged(bool enabled)
Compositing was enabled or disabled.
QWindow * focusWindow()
int right() const const
unsigned char * data
Image data for the icon.
Definition: netwm_def.h:168
Convenience access to certain properties and features of the window manager.
Definition: kwindowsystem.h:44
static int viewportToDesktop(const QPoint &pos)
void event(xcb_generic_event_t *event, unsigned long *properties, int properties_size)
This function takes the passed XEvent and returns an OR&#39;ed list of NETRootInfo properties that have c...
Definition: netwm.cpp:1633
int right
Right border of the strut.
Definition: netwm_def.h:252
void activate()
Window Managers must call this after creating the NETRootInfo object, and before using any other meth...
Definition: netwm.cpp:578
void screenAdded(QScreen *screen)
int y
y coordinate
Definition: netwm_def.h:51
const T & at(int i) const const
bool isNull() const const
load the standard X icon (last fallback)
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
This class provides information about a given window in the platform specific windowing system...
Definition: kwindowinfo.h:62
void setBlockingCompositing(bool active)
Sets whether the client wishes to block compositing (for better performance)
Definition: netwm.cpp:4842
int height() const const
void screenRemoved(QScreen *screen)
QRect boundingRect() const const
void geometryChanged(const QRect &geometry)
Partial strut class for NET classes.
Definition: netwm_def.h:180
QString join(const QString &separator) const const
bool isNull() const const
QThread * thread() const const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString tr(const char *sourceText, const char *disambiguation, int n)
Common API for root window properties/protocols.
Definition: netwm.h:40
int x() const const
int y() const const
int left
Left border of the strut.
Definition: netwm_def.h:247
indicates that a window should not be visible on the screen (e.g.
Definition: netwm_def.h:550
static void setExtendedStrut(WId win, int left_width, int left_start, int left_end, int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, int bottom_width, int bottom_start, int bottom_end)
Sets the strut of window win to left_width ranging from left_start to left_end on the left edge...
static void clearState(WId win, NET::States state)
Clears the state of window win from state.
virtual bool event(QEvent *e)
QVector< V > values(const QMultiHash< K, V > &c)
NETIcon icon(int width=-1, int height=-1) const
Returns an icon.
Definition: netwm.cpp:3524
indicates that the request comes from a normal application
Definition: netwm_def.h:846
static int currentDesktop()
Returns the current virtual desktop.
int count(const T &value) const const
NETSize size
Size of the rectangle.
Definition: netwm_def.h:133
QString fromLocal8Bit(const char *str, int size)
void append(const T &value)
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result)=0
static WId activeWindow()
Returns the currently active window, or 0 if no window is active.
QString fromUtf8(const char *str, int size)
xcb_connection_t * xcbConnection() const
Returns the xcb connection used.
Definition: netwm.cpp:4899
WindowType
Window type.
Definition: netwm_def.h:357
int top() const const
QCA_EXPORT bool isSupported(const char *features, const QString &provider=QString())
int x
x coordinate.
Definition: netwm_def.h:51
NETSize size
Size of the icon.
Definition: netwm_def.h:161
void setTop(int y)
int left() const const
void windowAdded(WId id)
A window has been added.
int removeAll(const T &value)
const char * constData() const const
NETPoint pos
Position of the rectangle.
Definition: netwm_def.h:126
Simple point class for NET classes.
Definition: netwm_def.h:27
QPoint center() const const
QCoreApplication * instance()
load icon after getting name from the classhint
read from property from the window manager specification
int top_width
Top border of the strut, width and range.
Definition: netwm_def.h:213
QRect intersected(const QRect &rectangle) const const
QMetaMethod fromSignal(PointerToMemberFunction signal)
void installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
static QPoint desktopToViewport(int desktop, bool absolute)
static QPoint constrainViewportRelativePosition(const QPoint &pos)
static void setState(WId win, NET::States state)
Sets the state of window win to state.
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
QList< QScreen * > screens()
bool isNull() const const
xcb_pixmap_t icccmIconPixmapMask() const
Returns the mask for the icon pixmap as set in WM_HINTS.
Definition: netwm.cpp:4795
void showingDesktopChanged(bool showing)
The state of showing the desktop has changed.
int height() const const
void windowRemoved(WId id)
A window has been removed.
bool contains(const T &value) const const
Simple rectangle class for NET classes.
Definition: netwm_def.h:105
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
QCA_EXPORT void init()
static KWindowSystem * self()
Access to the singleton instance.
void workAreaChanged()
The workarea has changed.
int desktop(bool ignore_viewport=false) const
Returns the desktop where the window is residing.
Definition: netwm.cpp:4718
if(recurs()&&!first)
static QList< WId > windows()
Returns the list of all toplevel windows currently managed by the window manager in the order of crea...
void setRight(int x)
indicated that the request comes from pager or similar tool
Definition: netwm_def.h:850
void setExtendedStrut(const NETExtendedStrut &extended_strut)
Set the extended (partial) strut for the application window.
Definition: netwm.cpp:2730
KGuiItem yes()
void currentDesktopChanged(int desktop)
Switched to another virtual desktop.
QByteArray toLatin1() const const
static bool mapViewport()
int width() const const
read from WMHints property
there was an attempt to activate this window, but the window manager prevented this.
Definition: netwm_def.h:565
static bool showingDesktop()
Returns the state of showing the desktop.
void activateWindow()
void stackingOrderChanged()
Emitted when the stacking order of the window changed.
static const int OnAllDesktops
Sentinel value to indicate that the client wishes to be visible on all desktops.
Definition: netwm.h:1659
bool isNull() const const
static void setOnAllDesktops(WId win, bool b)
Sets window win to be present on all virtual desktops if is true.
static int numberOfDesktops()
Returns the number of virtual desktops.
IgnoreAspectRatio
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int width
Width.
Definition: netwm_def.h:91
void setStrut(NETStrut strut)
Definition: netwm.cpp:2755
int height() const const
void numberOfDesktopsChanged(int num)
The number of desktops changed.
int bottom() const const
QPoint topLeft() const const
int right_width
Right border of the strut, width and range.
Definition: netwm_def.h:208
QSize size() const const
static QPixmap icon(WId win, int width=-1, int height=-1, bool scale=false)
Returns an icon for window win.
uchar * bits()
void setUserTime(xcb_timestamp_t time)
Sets user timestamp time on the window (property _NET_WM_USER_TIME).
Definition: netwm.cpp:3578
void setState(NET::States state, NET::States mask)
Set the state for the application window (see the NET base class documentation for a description of w...
Definition: netwm.cpp:2791
QIcon fromTheme(const QString &name)
Common API for application window properties/protocols.
Definition: netwm.h:944
int height
Height.
Definition: netwm_def.h:92
int left_width
Left border of the strut, width and range.
Definition: netwm_def.h:203
QImage toImage() const const
void strutChanged()
Something changed with the struts, may or may not have changed the work area.
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
void setIcon(NETIcon icon, bool replace=true)
Set icons for the application window.
Definition: netwm.cpp:2641
NETStrut strut() const
Definition: netwm.cpp:4632
BlockingQueuedConnection
void activeWindowChanged(WId id)
Hint that <Window> is active (= has focus) now.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const char * windowClassClass() const
Returns the class component of the window class for the window (i.e.
Definition: netwm.cpp:4800
static QList< WId > stackingOrder()
Returns the list of all toplevel windows currently managed by the window manager in the current stack...
void setLeft(int x)
xcb_pixmap_t icccmIconPixmap() const
Returns the icon pixmap as set in WM_HINTS.
Definition: netwm.cpp:4790
SmoothTransformation
int top
Top border of the strut.
Definition: netwm_def.h:257
QList::iterator begin()
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
Q_EMITQ_EMIT
Simple size class for NET classes.
Definition: netwm_def.h:68
indicates that the Window Manager SHOULD keep the window&#39;s position fixed on the screen, even when the virtual desktop scrolls.
Definition: netwm_def.h:510
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Oct 15 2021 22:41:50 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.