KWin
Loading...
Searching...
No Matches
layers.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10
11// SELI zmenit doc
12
13/*
14
15 This file contains things relevant to stacking order and layers.
16
17 Design:
18
19 Normal unconstrained stacking order, as requested by the user (by clicking
20 on windows to raise them, etc.), is in Workspace::unconstrained_stacking_order.
21 That list shouldn't be used at all, except for building
22 Workspace::stacking_order. The building is done
23 in Workspace::constrainedStackingOrder(). Only Workspace::stackingOrder() should
24 be used to get the stacking order, because it also checks the stacking order
25 is up to date.
26 All clients are also stored in Workspace::clients (except for isDesktop() clients,
27 as those are very special, and are stored in Workspace::desktops), in the order
28 the clients were created.
29
30 Every window has one layer assigned in which it is. There are 7 layers,
31 from bottom : DesktopLayer, BelowLayer, NormalLayer, DockLayer, AboveLayer, NotificationLayer,
32 ActiveLayer, CriticalNotificationLayer, and OnScreenDisplayLayer (see also NETWM sect.7.10.).
33 The layer a window is in depends on the window type, and on other things like whether the window
34 is active. We extend the layers provided in NETWM by the NotificationLayer, OnScreenDisplayLayer,
35 and CriticalNotificationLayer.
36 The NoficationLayer contains notification windows which are kept above all windows except the active
37 fullscreen window. The CriticalNotificationLayer contains notification windows which are important
38 enough to keep them even above fullscreen windows. The OnScreenDisplayLayer is used for eg. volume
39 and brightness change feedback and is kept above all windows since it provides immediate response
40 to a user action.
41
42 NET::Splash clients belong to the Normal layer. NET::TopMenu clients
43 belong to Dock layer. Clients that are both NET::Dock and NET::KeepBelow
44 are in the Normal layer in order to keep the 'allow window to cover
45 the panel' Kicker setting to work as intended (this may look like a slight
46 spec violation, but a) I have no better idea, b) the spec allows adjusting
47 the stacking order if the WM thinks it's a good idea . We put all
48 NET::KeepAbove above all Docks too, even though the spec suggests putting
49 them in the same layer.
50
51 Most transients are in the same layer as their mainwindow,
52 see Workspace::constrainedStackingOrder(), they may also be in higher layers, but
53 they should never be below their mainwindow.
54
55 Currently the things that affect client in which layer a client
56 belongs: KeepAbove/Keep Below flags, window type, fullscreen
57 state and whether the client is active, mainclient (transiency).
58
59 Make sure updateStackingOrder() is called in order to make
60 Workspace::stackingOrder() up to date and propagated to the world.
61 Using Workspace::blockStackingUpdates() (or the StackingUpdatesBlocker
62 helper class) it's possible to temporarily disable updates
63 and the stacking order will be updated once after it's allowed again.
64
65*/
66
67#include "compositor.h"
69#include "focuschain.h"
70#include "group.h"
71#include "internalwindow.h"
72#include "netinfo.h"
73#include "rules.h"
74#include "screenedge.h"
75#include "tabbox/tabbox.h"
76#include "utils/common.h"
77#include "virtualdesktops.h"
78#include "wayland_server.h"
79#include "workspace.h"
80#include "x11window.h"
81
82#include <array>
83
84#include <QDebug>
85
86namespace KWin
87{
88
89//*******************************
90// Workspace
91//*******************************
92
93void Workspace::updateStackingOrder(bool propagate_new_windows)
94{
95 if (m_blockStackingUpdates > 0) {
96 if (propagate_new_windows) {
97 m_blockedPropagatingNewWindows = true;
98 }
99 return;
100 }
101 QList<Window *> new_stacking_order = constrainedStackingOrder();
102 bool changed = (force_restacking || new_stacking_order != stacking_order);
103 force_restacking = false;
104 stacking_order = new_stacking_order;
105 if (changed || propagate_new_windows) {
106 propagateWindows(propagate_new_windows);
107
108 for (int i = 0; i < stacking_order.size(); ++i) {
109 stacking_order[i]->setStackingOrder(i);
110 }
111
112 Q_EMIT stackingOrderChanged();
113
114 if (m_activeWindow) {
115 m_activeWindow->updateMouseGrab();
116 }
117 }
118}
119
128{
129 if (!rootInfo()) {
130 return;
131 }
132 Xcb::restackWindows(QList<xcb_window_t>() << rootInfo()->supportWindow() << workspace()->screenEdges()->windows());
133}
134
139void Workspace::propagateWindows(bool propagate_new_windows)
140{
141 if (!rootInfo()) {
142 return;
143 }
144 // restack the windows according to the stacking order
145 // supportWindow > electric borders > windows > hidden windows
146 QList<xcb_window_t> newWindowStack;
147
148 // Stack all windows under the support window. The support window is
149 // not used for anything (besides the NETWM property), and it's not shown,
150 // but it was lowered after kwin startup. Stacking all windows below
151 // it ensures that no window will be ever shown above override-redirect
152 // windows (e.g. popups).
153 newWindowStack << rootInfo()->supportWindow();
154
155 newWindowStack << workspace()->screenEdges()->windows();
156
157 newWindowStack << manual_overlays;
158
159 newWindowStack.reserve(newWindowStack.size() + 2 * stacking_order.size()); // *2 for inputWindow
160
161 for (int i = stacking_order.size() - 1; i >= 0; --i) {
162 X11Window *window = qobject_cast<X11Window *>(stacking_order.at(i));
163 if (!window || window->isUnmanaged() || window->hiddenPreview()) {
164 continue;
165 }
166
167 if (window->inputId()) {
168 // Stack the input window above the frame
169 newWindowStack << window->inputId();
170 }
171
172 newWindowStack << window->frameId();
173 }
174
175 // when having hidden previews, stack hidden windows below everything else
176 // (as far as pure X stacking order is concerned), in order to avoid having
177 // these windows that should be unmapped to interfere with other windows
178 for (int i = stacking_order.size() - 1; i >= 0; --i) {
179 X11Window *window = qobject_cast<X11Window *>(stacking_order.at(i));
180 if (!window || window->isUnmanaged() || !window->hiddenPreview()) {
181 continue;
182 }
183 newWindowStack << window->frameId();
184 }
185 // TODO isn't it too inefficient to restack always all windows?
186 // TODO don't restack not visible windows?
187 Q_ASSERT(newWindowStack.at(0) == rootInfo()->supportWindow());
188 Xcb::restackWindows(newWindowStack);
189
190 QList<xcb_window_t> cl;
191 if (propagate_new_windows) {
192 cl.reserve(manual_overlays.size() + m_windows.size());
193 for (const auto win : std::as_const(manual_overlays)) {
194 cl.push_back(win);
195 }
196 for (Window *window : std::as_const(m_windows)) {
197 X11Window *x11Window = qobject_cast<X11Window *>(window);
198 if (x11Window && !x11Window->isUnmanaged()) {
199 cl.push_back(x11Window->window());
200 }
201 }
202 rootInfo()->setClientList(cl.constData(), cl.size());
203 }
204
205 cl.clear();
206 for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) {
207 X11Window *window = qobject_cast<X11Window *>(*it);
208 if (window && !window->isUnmanaged()) {
209 cl.push_back(window->window());
210 }
211 }
212 for (const auto win : std::as_const(manual_overlays)) {
213 cl.push_back(win);
214 }
215 rootInfo()->setClientListStacking(cl.constData(), cl.size());
216}
217
223// TODO misleading name for this method, too many slightly different ways to use it
224Window *Workspace::topWindowOnDesktop(VirtualDesktop *desktop, Output *output, bool unconstrained, bool only_normal) const
225{
226 // TODO Q_ASSERT( block_stacking_updates == 0 );
227 QList<Window *> list;
228 if (!unconstrained) {
229 list = stacking_order;
230 } else {
231 list = unconstrained_stacking_order;
232 }
233 for (int i = list.size() - 1; i >= 0; --i) {
234 auto window = list.at(i);
235 if (!window->isClient() || window->isDeleted()) {
236 continue;
237 }
238 if (window->isOnDesktop(desktop) && window->isShown() && window->isOnCurrentActivity() && !window->isShade()) {
239 if (output && window->output() != output) {
240 continue;
241 }
242 if (!only_normal) {
243 return window;
244 }
245 if (window->wantsTabFocus() && !window->isSpecialWindow()) {
246 return window;
247 }
248 }
249 }
250 return nullptr;
251}
252
253Window *Workspace::findDesktop(bool topmost, VirtualDesktop *desktop) const
254{
255 // TODO Q_ASSERT( block_stacking_updates == 0 );
256 if (topmost) {
257 for (int i = stacking_order.size() - 1; i >= 0; i--) {
258 auto window = stacking_order.at(i);
259 if (window->isDeleted()) {
260 continue;
261 }
262 if (window->isClient() && window->isOnDesktop(desktop) && window->isDesktop() && window->isShown()) {
263 return window;
264 }
265 }
266 } else { // bottom-most
267 for (Window *window : std::as_const(stacking_order)) {
268 if (window->isDeleted()) {
269 continue;
270 }
271 if (window->isClient() && window->isOnDesktop(desktop) && window->isDesktop() && window->isShown()) {
272 return window;
273 }
274 }
275 }
276 return nullptr;
277}
278
280{
281 if (!window->isOnCurrentDesktop()) {
282 return;
283 }
284
285 const Window *topmost =
286 topWindowOnDesktop(VirtualDesktopManager::self()->currentDesktop(),
287 options->isSeparateScreenFocus() ? window->output() : nullptr);
288
289 if (window == topmost) {
290 lowerWindow(window);
291 } else {
292 raiseWindow(window);
293 }
294}
295
296void Workspace::lowerWindow(Window *window, bool nogroup)
297{
298 if (window->isDeleted()) {
299 qCWarning(KWIN_CORE) << "Workspace::lowerWindow: closed window" << window << "cannot be restacked";
300 return;
301 }
302
303 window->cancelAutoRaise();
304
305 StackingUpdatesBlocker blocker(this);
306
307 unconstrained_stacking_order.removeAll(window);
308 unconstrained_stacking_order.prepend(window);
309 if (!nogroup && window->isTransient()) {
310 // lower also all windows in the group, in their reversed stacking order
311 QList<X11Window *> wins;
312 if (auto group = window->group()) {
313 wins = ensureStackingOrder(group->members());
314 }
315 for (int i = wins.size() - 1; i >= 0; --i) {
316 if (wins[i] != window) {
317 lowerWindow(wins[i], true);
318 }
319 }
320 }
321}
322
323void Workspace::lowerWindowWithinApplication(Window *window)
324{
325 if (window->isDeleted()) {
326 qCWarning(KWIN_CORE) << "Workspace::lowerWindowWithinApplication: closed window" << window << "cannot be restacked";
327 return;
328 }
329
330 window->cancelAutoRaise();
331
332 StackingUpdatesBlocker blocker(this);
333
334 unconstrained_stacking_order.removeAll(window);
335 bool lowered = false;
336 // first try to put it below the bottom-most window of the application
337 for (auto it = unconstrained_stacking_order.begin(); it != unconstrained_stacking_order.end(); ++it) {
338 auto other = *it;
339 if (!other->isClient() || other->isDeleted()) {
340 continue;
341 }
342 if (Window::belongToSameApplication(other, window)) {
343 unconstrained_stacking_order.insert(it, window);
344 lowered = true;
345 break;
346 }
347 }
348 if (!lowered) {
349 unconstrained_stacking_order.prepend(window);
350 }
351 // ignore mainwindows
352}
353
354void Workspace::raiseWindow(Window *window, bool nogroup)
355{
356 if (window->isDeleted()) {
357 qCWarning(KWIN_CORE) << "Workspace::raiseWindow: closed window" << window << "cannot be restacked";
358 return;
359 }
360
361 window->cancelAutoRaise();
362
363 StackingUpdatesBlocker blocker(this);
364
365 if (!nogroup && window->isTransient()) {
366 QList<Window *> transients;
367 Window *transient_parent = window;
368 while ((transient_parent = transient_parent->transientFor())) {
369 transients.prepend(transient_parent);
370 }
371 for (const auto &transient_parent : std::as_const(transients)) {
372 raiseWindow(transient_parent, true);
373 }
374 }
375
376 unconstrained_stacking_order.removeAll(window);
377 unconstrained_stacking_order.append(window);
378}
379
380void Workspace::raiseWindowWithinApplication(Window *window)
381{
382 if (window->isDeleted()) {
383 qCWarning(KWIN_CORE) << "Workspace::raiseWindowWithinApplication: closed window" << window << "cannot be restacked";
384 return;
385 }
386
387 window->cancelAutoRaise();
388
389 StackingUpdatesBlocker blocker(this);
390 // ignore mainwindows
391
392 // first try to put it above the top-most window of the application
393 for (int i = unconstrained_stacking_order.size() - 1; i > -1; --i) {
394 auto other = unconstrained_stacking_order.at(i);
395 if (!other->isClient() || other->isDeleted()) {
396 continue;
397 }
398 if (other == window) { // don't lower it just because it asked to be raised
399 return;
400 }
401 if (Window::belongToSameApplication(other, window)) {
402 unconstrained_stacking_order.removeAll(window);
403 unconstrained_stacking_order.insert(unconstrained_stacking_order.indexOf(other) + 1, window); // insert after the found one
404 break;
405 }
406 }
407}
408
409void Workspace::raiseWindowRequest(Window *window, NET::RequestSource src, xcb_timestamp_t timestamp)
410{
411 if (src == NET::FromTool || allowFullClientRaising(window, timestamp)) {
412 raiseWindow(window);
413 } else {
414 raiseWindowWithinApplication(window);
415 window->demandAttention();
416 }
417}
418
419void Workspace::lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t /*timestamp*/)
420{
421 // If the window has support for all this focus stealing prevention stuff,
422 // do only lowering within the application, as that's the more logical
423 // variant of lowering when application requests it.
424 // No demanding of attention here of course.
425 if (src == NET::FromTool || !window->hasUserTimeSupport()) {
426 lowerWindow(window);
427 } else {
428 lowerWindowWithinApplication(window);
429 }
430}
431
433{
434 lowerWindowWithinApplication(window);
435}
436
437void Workspace::restack(Window *window, Window *under, bool force)
438{
439 if (window->isDeleted()) {
440 qCWarning(KWIN_CORE) << "Workspace::restack: closed window" << window << "cannot be restacked";
441 return;
442 }
443 Q_ASSERT(unconstrained_stacking_order.contains(under));
444 if (!force && !Window::belongToSameApplication(under, window)) {
445 // put in the stacking order below _all_ windows belonging to the active application
446 for (int i = 0; i < unconstrained_stacking_order.size(); ++i) {
447 auto other = unconstrained_stacking_order.at(i);
448 if (other->isClient() && other->layer() == window->layer() && Window::belongToSameApplication(under, other)) {
449 under = (window == other) ? nullptr : other;
450 break;
451 }
452 }
453 }
454 if (under) {
455 unconstrained_stacking_order.removeAll(window);
456 unconstrained_stacking_order.insert(unconstrained_stacking_order.indexOf(under), window);
457 }
458
459 Q_ASSERT(unconstrained_stacking_order.contains(window));
460 m_focusChain->moveAfterWindow(window, under);
462}
463
465{
466 if (!m_activeWindow || m_activeWindow == window || m_activeWindow->layer() != window->layer()) {
467 raiseWindow(window);
468 return;
469 }
470 restack(window, m_activeWindow);
471}
472
474{
475 if (window->sessionStackingOrder() < 0) {
476 return;
477 }
478 StackingUpdatesBlocker blocker(this);
479 unconstrained_stacking_order.removeAll(window);
480 for (auto it = unconstrained_stacking_order.begin(); it != unconstrained_stacking_order.end(); ++it) {
481 X11Window *current = qobject_cast<X11Window *>(*it);
482 if (!current || current->isDeleted() || current->isUnmanaged()) {
483 continue;
484 }
485 if (current->sessionStackingOrder() > window->sessionStackingOrder()) {
486 unconstrained_stacking_order.insert(it, window);
487 return;
488 }
489 }
490 unconstrained_stacking_order.append(window);
491}
492
493static Layer layerForWindow(const X11Window *window)
494{
495 Layer layer = window->layer();
496
497 // Desktop windows cannot be promoted to upper layers.
498 if (layer == DesktopLayer) {
499 return layer;
500 }
501
502 if (const Group *group = window->group()) {
503 const auto members = group->members();
504 for (const X11Window *member : members) {
505 if (member == window) {
506 continue;
507 } else if (member->output() != window->output()) {
508 continue;
509 }
510 if (member->layer() == ActiveLayer) {
511 return ActiveLayer;
512 }
513 }
514 }
515
516 return layer;
517}
518
519static Layer computeLayer(const Window *window)
520{
521 if (auto x11Window = qobject_cast<const X11Window *>(window)) {
522 return layerForWindow(x11Window);
523 } else {
524 return window->layer();
525 }
526}
527
531QList<Window *> Workspace::constrainedStackingOrder()
532{
533 // Sort the windows based on their layers while preserving their relative order in the
534 // unconstrained stacking order.
535 std::array<QList<Window *>, NumLayers> windows;
536 for (Window *window : std::as_const(unconstrained_stacking_order)) {
537 const Layer layer = computeLayer(window);
538 windows[layer] << window;
539 }
540
541 QList<Window *> stacking;
542 stacking.reserve(unconstrained_stacking_order.count());
543 for (uint layer = FirstLayer; layer < NumLayers; ++layer) {
544 stacking += windows[layer];
545 }
546
547 // Apply the stacking order constraints. First, we enqueue the root constraints, i.e.
548 // the ones that are not affected by other constraints.
549 QList<Constraint *> constraints;
550 constraints.reserve(m_constraints.count());
551 for (Constraint *constraint : std::as_const(m_constraints)) {
552 if (constraint->parents.isEmpty()) {
553 constraint->enqueued = true;
554 constraints.append(constraint);
555 } else {
556 constraint->enqueued = false;
557 }
558 }
559
560 // Preserve the relative order of transient siblings in the unconstrained stacking order.
561 auto constraintComparator = [&stacking](Constraint *a, Constraint *b) {
562 return stacking.indexOf(a->above) > stacking.indexOf(b->above);
563 };
564 std::sort(constraints.begin(), constraints.end(), constraintComparator);
565
566 // Once we've enqueued all the root constraints, we traverse the constraints tree in
567 // the reverse breadth-first search fashion. A constraint is applied only if its condition is
568 // not met.
569 while (!constraints.isEmpty()) {
570 Constraint *constraint = constraints.takeFirst();
571
572 const int belowIndex = stacking.indexOf(constraint->below);
573 const int aboveIndex = stacking.indexOf(constraint->above);
574 if (belowIndex == -1 || aboveIndex == -1) {
575 continue;
576 } else if (aboveIndex < belowIndex) {
577 stacking.removeAt(aboveIndex);
578 stacking.insert(belowIndex, constraint->above);
579 }
580
581 // Preserve the relative order of transient siblings in the unconstrained stacking order.
582 QList<Constraint *> children = constraint->children;
583 std::sort(children.begin(), children.end(), constraintComparator);
584
585 for (Constraint *child : std::as_const(children)) {
586 if (!child->enqueued) {
587 child->enqueued = true;
588 constraints.append(child);
589 }
590 }
591 }
592
593 return stacking;
594}
595
596void Workspace::blockStackingUpdates(bool block)
597{
598 if (block) {
599 if (m_blockStackingUpdates == 0) {
600 m_blockedPropagatingNewWindows = false;
601 }
602 ++m_blockStackingUpdates;
603 } else // !block
604 if (--m_blockStackingUpdates == 0) {
605 updateStackingOrder(m_blockedPropagatingNewWindows);
606 if (effects) {
608 }
609 }
610}
611
612namespace
613{
614template<class T>
615QList<T *> ensureStackingOrderInList(const QList<Window *> &stackingOrder, const QList<T *> &list)
616{
617 static_assert(std::is_base_of<Window, T>::value,
618 "U must be derived from T");
619 // TODO Q_ASSERT( block_stacking_updates == 0 );
620 if (list.count() < 2) {
621 return list;
622 }
623 // TODO is this worth optimizing?
624 QList<T *> result = list;
625 for (auto it = stackingOrder.begin(); it != stackingOrder.end(); ++it) {
626 T *window = qobject_cast<T *>(*it);
627 if (!window) {
628 continue;
629 }
630 if (result.removeAll(window) != 0) {
631 result.append(window);
632 }
633 }
634 return result;
635}
636}
637
638// Ensure list is in stacking order
639QList<X11Window *> Workspace::ensureStackingOrder(const QList<X11Window *> &list) const
640{
641 return ensureStackingOrderInList(stacking_order, list);
642}
643
644QList<Window *> Workspace::ensureStackingOrder(const QList<Window *> &list) const
645{
646 return ensureStackingOrderInList(stacking_order, list);
647}
648
650{
651 return unconstrained_stacking_order;
652}
653
654void Workspace::updateXStackingOrder()
655{
656 // we use our stacking order for managed windows, but X's for override-redirect windows
657 Xcb::Tree tree(kwinApp()->x11RootWindow());
658 xcb_window_t *windows = tree.children();
659
660 const auto count = tree.data()->children_len;
661 bool changed = false;
662 for (unsigned int i = 0; i < count; ++i) {
663 auto window = findUnmanaged(windows[i]);
664 if (window) {
665 unconstrained_stacking_order.removeAll(window);
666 unconstrained_stacking_order.append(window);
667 changed = true;
668 }
669 }
670
671 if (changed) {
673 }
674}
675
676//*******************************
677// Client
678//*******************************
679
680void X11Window::restackWindow(xcb_window_t above, int detail, NET::RequestSource src, xcb_timestamp_t timestamp, bool send_event)
681{
682 X11Window *other = nullptr;
683 if (detail == XCB_STACK_MODE_OPPOSITE) {
685 if (!other) {
687 return;
688 }
689 auto it = workspace()->stackingOrder().constBegin(),
690 end = workspace()->stackingOrder().constEnd();
691 while (it != end) {
692 if (*it == this) {
693 detail = XCB_STACK_MODE_ABOVE;
694 break;
695 } else if (*it == other) {
696 detail = XCB_STACK_MODE_BELOW;
697 break;
698 }
699 ++it;
700 }
701 } else if (detail == XCB_STACK_MODE_TOP_IF) {
703 if (other && other->frameGeometry().intersects(frameGeometry())) {
704 workspace()->raiseWindowRequest(this, src, timestamp);
705 }
706 return;
707 } else if (detail == XCB_STACK_MODE_BOTTOM_IF) {
709 if (other && other->frameGeometry().intersects(frameGeometry())) {
710 workspace()->lowerWindowRequest(this, src, timestamp);
711 }
712 return;
713 }
714
715 if (!other) {
717 }
718
719 if (other && detail == XCB_STACK_MODE_ABOVE) {
720 auto it = workspace()->stackingOrder().constEnd(),
721 begin = workspace()->stackingOrder().constBegin();
722 while (--it != begin) {
723
724 if (*it == other) { // the other one is top on stack
725 it = begin; // invalidate
726 src = NET::FromTool; // force
727 break;
728 }
729 X11Window *window = qobject_cast<X11Window *>(*it);
730
731 if (!window || !((*it)->isNormalWindow() && window->isShown() && (*it)->isOnCurrentDesktop() && (*it)->isOnCurrentActivity() && (*it)->isOnOutput(output()))) {
732 continue; // irrelevant windows
733 }
734
735 if (*(it - 1) == other) {
736 break; // "it" is the one above the target one, stack below "it"
737 }
738 }
739
740 if (it != begin && (*(it - 1) == other)) {
741 other = qobject_cast<X11Window *>(*it);
742 } else {
743 other = nullptr;
744 }
745 }
746
747 if (other) {
748 workspace()->restack(this, other);
749 } else if (detail == XCB_STACK_MODE_BELOW) {
750 workspace()->lowerWindowRequest(this, src, timestamp);
751 } else if (detail == XCB_STACK_MODE_ABOVE) {
752 workspace()->raiseWindowRequest(this, src, timestamp);
753 }
754
755 if (send_event) {
756 sendSyntheticConfigureNotify();
757 }
758}
759
761{
762 const auto members = group()->members();
763 for (const X11Window *window : members) {
764 if (window->isDesktop()) {
765 return true;
766 }
767 }
768 return false;
769}
770
771} // namespace
const QList< X11Window * > & members() const
Definition group.h:68
bool isSeparateScreenFocus() const
Definition options.h:318
QList< xcb_window_t > windows() const
QRectF frameGeometry
Definition window.h:431
virtual void updateMouseGrab()
Definition window.cpp:422
virtual bool isTransient() const
Definition window.cpp:2290
void cancelAutoRaise()
Definition window.cpp:679
static bool belongToSameApplication(const Window *c1, const Window *c2, SameApplicationChecks checks=SameApplicationChecks())
Definition window.cpp:426
void demandAttention(bool set=true)
Definition window.cpp:708
bool isOnCurrentDesktop() const
Definition window.cpp:848
KWin::Window * transientFor
Definition window.h:420
KWin::Layer layer
Definition window.h:529
KWin::Output * output
Definition window.h:111
virtual const Group * group() const
Definition window.cpp:3238
bool isDeleted() const
Definition window.cpp:540
X11Window * findUnmanaged(std::function< bool(const X11Window *)> func) const
ScreenEdges * screenEdges() const
void lowerWindowRequest(X11Window *window, NET::RequestSource src, xcb_timestamp_t timestamp)
Definition layers.cpp:419
X11Window * findClient(std::function< bool(const X11Window *)> func) const
Finds the first Client matching the condition expressed by passed in func.
const QList< Window * > & stackingOrder() const
Definition workspace.h:788
void raiseWindowRequest(Window *window, NET::RequestSource src=NET::FromApplication, xcb_timestamp_t timestamp=0)
Definition layers.cpp:409
void stackScreenEdgesUnderOverrideRedirect()
Definition layers.cpp:127
void stackingOrderChanged()
Window * findDesktop(bool topmost, VirtualDesktop *desktop) const
Definition layers.cpp:253
friend Workspace * workspace()
Definition workspace.h:830
void restack(Window *window, Window *under, bool force=false)
Definition layers.cpp:437
void updateStackingOrder(bool propagate_new_windows=false)
Definition layers.cpp:93
void raiseWindow(Window *window, bool nogroup=false)
Definition layers.cpp:354
Window * topWindowOnDesktop(VirtualDesktop *desktop, Output *output=nullptr, bool unconstrained=false, bool only_normal=true) const
Definition layers.cpp:224
QList< Window * > unconstrainedStackingOrder() const
Definition layers.cpp:649
void lowerWindow(Window *window, bool nogroup=false)
Definition layers.cpp:296
const QList< Window * > windows() const
Definition workspace.h:248
friend class StackingUpdatesBlocker
Definition workspace.h:704
void restoreSessionStackingOrder(X11Window *window)
Definition layers.cpp:473
void restackWindowUnderActive(Window *window)
Definition layers.cpp:464
void raiseOrLowerWindow(Window *window)
Definition layers.cpp:279
QList< X11Window * > ensureStackingOrder(const QList< X11Window * > &windows) const
Definition layers.cpp:639
bool hasUserTimeSupport() const
Definition x11window.h:610
int sessionStackingOrder() const
Definition x11window.h:590
void restackWindow(xcb_window_t above, int detail, NET::RequestSource source, xcb_timestamp_t timestamp, bool send_event=false)
Definition layers.cpp:680
bool belongsToDesktop() const override
Definition layers.cpp:760
bool isUnmanaged() const override
xcb_window_t window() const
const Group * group() const override
Definition x11window.h:565
RootInfo * rootInfo()
Definition netinfo.h:59
Workspace * workspace()
Definition workspace.h:830
Options * options
Definition main.cpp:73
Layer
Definition globals.h:162
@ DesktopLayer
Definition globals.h:165
@ ActiveLayer
Definition globals.h:170
@ NumLayers
Definition globals.h:175
@ FirstLayer
Definition globals.h:164
EffectsHandler * effects