1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | *********************************************************************/ |
20 | |
21 | #include "unmanaged.h" |
22 | |
23 | #include "workspace.h" |
24 | #include "effects.h" |
25 | #include "deleted.h" |
26 | #include "xcbutils.h" |
27 | |
28 | #include <QTimer> |
29 | #include <QDebug> |
30 | |
31 | #include <X11/extensions/shape.h> |
32 | |
33 | namespace KWin |
34 | { |
35 | |
36 | Unmanaged::Unmanaged() |
37 | : Toplevel() |
38 | { |
39 | ready_for_painting = false; |
40 | connect(this, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SIGNAL(geometryChanged())); |
41 | QTimer::singleShot(50, this, SLOT(setReadyForPainting())); |
42 | } |
43 | |
44 | Unmanaged::~Unmanaged() |
45 | { |
46 | } |
47 | |
48 | bool Unmanaged::track(Window w) |
49 | { |
50 | XWindowAttributes attr; |
51 | grabXServer(); |
52 | if (!XGetWindowAttributes(display(), w, &attr) || attr.map_state != IsViewable) { |
53 | ungrabXServer(); |
54 | return false; |
55 | } |
56 | if (attr.c_class == InputOnly) { |
57 | ungrabXServer(); |
58 | return false; |
59 | } |
60 | setWindowHandles(w, w); // the window is also the frame |
61 | XSelectInput(display(), w, attr.your_event_mask | StructureNotifyMask | PropertyChangeMask); |
62 | geom = QRect(attr.x, attr.y, attr.width, attr.height); |
63 | checkScreen(); |
64 | vis = attr.visual; |
65 | bit_depth = attr.depth; |
66 | unsigned long properties[ 2 ]; |
67 | properties[ NETWinInfo::PROTOCOLS ] = |
68 | NET::WMWindowType | |
69 | NET::WMPid | |
70 | 0; |
71 | properties[ NETWinInfo::PROTOCOLS2 ] = |
72 | NET::WM2Opacity | |
73 | 0; |
74 | info = new NETWinInfo2(display(), w, rootWindow(), properties, 2); |
75 | getResourceClass(); |
76 | getWindowRole(); |
77 | getWmClientLeader(); |
78 | getWmClientMachine(); |
79 | if (Xcb::Extensions::self()->isShapeAvailable()) |
80 | XShapeSelectInput(display(), w, ShapeNotifyMask); |
81 | detectShape(w); |
82 | getWmOpaqueRegion(); |
83 | getSkipCloseAnimation(); |
84 | setupCompositing(); |
85 | ungrabXServer(); |
86 | if (effects) |
87 | static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowStacking(); |
88 | return true; |
89 | } |
90 | |
91 | void Unmanaged::release(bool on_shutdown) |
92 | { |
93 | Deleted* del = NULL; |
94 | if (!on_shutdown) { |
95 | del = Deleted::create(this); |
96 | } |
97 | emit windowClosed(this, del); |
98 | finishCompositing(); |
99 | if (!QWidget::find(window())) { // don't affect our own windows |
100 | if (Xcb::Extensions::self()->isShapeAvailable()) |
101 | XShapeSelectInput(display(), window(), NoEventMask); |
102 | XSelectInput(display(), window(), NoEventMask); |
103 | } |
104 | if (!on_shutdown) { |
105 | workspace()->removeUnmanaged(this); |
106 | addWorkspaceRepaint(del->visibleRect()); |
107 | disownDataPassedToDeleted(); |
108 | del->unrefWindow(); |
109 | } |
110 | deleteUnmanaged(this); |
111 | } |
112 | |
113 | void Unmanaged::deleteUnmanaged(Unmanaged* c) |
114 | { |
115 | delete c; |
116 | } |
117 | |
118 | int Unmanaged::desktop() const |
119 | { |
120 | return NET::OnAllDesktops; // TODO for some window types should be the current desktop? |
121 | } |
122 | |
123 | QStringList Unmanaged::activities() const |
124 | { |
125 | return QStringList(); |
126 | } |
127 | |
128 | QPoint Unmanaged::clientPos() const |
129 | { |
130 | return QPoint(0, 0); // unmanaged windows don't have decorations |
131 | } |
132 | |
133 | QSize Unmanaged::clientSize() const |
134 | { |
135 | return size(); |
136 | } |
137 | |
138 | QRect Unmanaged::transparentRect() const |
139 | { |
140 | return QRect(clientPos(), clientSize()); |
141 | } |
142 | |
143 | void Unmanaged::debug(QDebug& stream) const |
144 | { |
145 | stream << "\'ID:" << window() << "\'" ; |
146 | } |
147 | |
148 | NET::WindowType Unmanaged::windowType(bool direct, int supportedTypes) const |
149 | { |
150 | // for unmanaged windows the direct does not make any difference |
151 | // as there are no rules to check and no hacks to apply |
152 | Q_UNUSED(direct) |
153 | if (supportedTypes == 0) { |
154 | supportedTypes = SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK; |
155 | } |
156 | return info->windowType(supportedTypes); |
157 | } |
158 | |
159 | } // namespace |
160 | |
161 | #include "unmanaged.moc" |
162 | |