1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 2003 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 "bridge.h" |
22 | |
23 | #include "client.h" |
24 | #include "options.h" |
25 | |
26 | #include <kconfiggroup.h> |
27 | #include "composite.h" |
28 | #include "workspace.h" |
29 | |
30 | namespace KWin |
31 | { |
32 | |
33 | Bridge::Bridge(Client* cl) |
34 | : c(cl) |
35 | { |
36 | } |
37 | |
38 | #define BRIDGE_HELPER( rettype, prototype, args1, args2, cst ) \ |
39 | rettype Bridge::prototype ( args1 ) cst \ |
40 | { \ |
41 | return c->prototype( args2 ); \ |
42 | } |
43 | |
44 | BRIDGE_HELPER(bool, isCloseable, , , const) |
45 | BRIDGE_HELPER(bool, isMaximizable, , , const) |
46 | BRIDGE_HELPER(Bridge::MaximizeMode, maximizeMode, , , const) |
47 | BRIDGE_HELPER(Bridge::QuickTileMode, quickTileMode, , , const) |
48 | BRIDGE_HELPER(bool, isMinimizable, , , const) |
49 | BRIDGE_HELPER(bool, providesContextHelp, , , const) |
50 | BRIDGE_HELPER(int, desktop, , , const) |
51 | BRIDGE_HELPER(bool, isModal, , , const) |
52 | BRIDGE_HELPER(bool, isShadeable, , , const) |
53 | BRIDGE_HELPER(bool, isShade, , , const) |
54 | BRIDGE_HELPER(bool, keepAbove, , , const) |
55 | BRIDGE_HELPER(bool, keepBelow, , , const) |
56 | BRIDGE_HELPER(bool, isMovable, , , const) |
57 | BRIDGE_HELPER(bool, isResizable, , , const) |
58 | BRIDGE_HELPER(void, processMousePressEvent, QMouseEvent* e, e,) |
59 | BRIDGE_HELPER(QRect, geometry, , , const) |
60 | BRIDGE_HELPER(void, closeWindow, , ,) |
61 | BRIDGE_HELPER(void, maximize, MaximizeMode m, m,) |
62 | BRIDGE_HELPER(void, minimize, , ,) |
63 | BRIDGE_HELPER(void, showContextHelp, , ,) |
64 | BRIDGE_HELPER(void, setDesktop, int desktop, desktop,) |
65 | |
66 | bool Bridge::isActive() const |
67 | { |
68 | return c->isActive() || (c->tabGroup() && c->tabGroup()->isActive()); |
69 | } |
70 | |
71 | void Bridge::setKeepAbove(bool set) |
72 | { |
73 | if (c->keepAbove() != set) |
74 | workspace()->performWindowOperation(c, KeepAboveOp); |
75 | } |
76 | |
77 | void Bridge::setKeepBelow(bool set) |
78 | { |
79 | if (c->keepBelow() != set) |
80 | workspace()->performWindowOperation(c, KeepBelowOp); |
81 | } |
82 | |
83 | NET::WindowType Bridge::windowType(unsigned long supported_types) const |
84 | { |
85 | return c->windowType(false, supported_types); |
86 | } |
87 | |
88 | QIcon Bridge::icon() const |
89 | { |
90 | QIcon ret(c->icon()); |
91 | ret.addPixmap(c->miniIcon()); |
92 | return ret; |
93 | } |
94 | |
95 | bool Bridge::isSetShade() const |
96 | { |
97 | return c->shadeMode() != ShadeNone; |
98 | } |
99 | |
100 | void Bridge::(const QPoint &p) |
101 | { |
102 | workspace()->showWindowMenu(QRect(p,p), c); |
103 | } |
104 | |
105 | void Bridge::(const QPoint &p, long id) |
106 | { |
107 | Client *cc = clientForId(id); |
108 | if (!cc) |
109 | cc = c; |
110 | workspace()->showWindowMenu(QRect(p,p), cc); |
111 | } |
112 | |
113 | void Bridge::(const QRect &p) |
114 | { |
115 | workspace()->showWindowMenu(p, c); |
116 | } |
117 | |
118 | void Bridge::(const QPoint &p) |
119 | { |
120 | #ifdef KWIN_BUILD_KAPPMENU |
121 | c->showApplicationMenu(p); |
122 | #endif |
123 | } |
124 | |
125 | bool Bridge::() const |
126 | { |
127 | #ifdef KWIN_BUILD_KAPPMENU |
128 | return c->menuAvailable(); |
129 | #else |
130 | return false; |
131 | #endif |
132 | } |
133 | |
134 | void Bridge::performWindowOperation(WindowOperation op) |
135 | { |
136 | workspace()->performWindowOperation(c, op); |
137 | } |
138 | |
139 | void Bridge::setMask(const QRegion& r, int mode) |
140 | { |
141 | c->setMask(r, mode); |
142 | } |
143 | |
144 | bool Bridge::isPreview() const |
145 | { |
146 | return false; |
147 | } |
148 | |
149 | QRect Bridge::iconGeometry() const |
150 | { |
151 | NETRect r = c->info->iconGeometry(); |
152 | return QRect(r.pos.x, r.pos.y, r.size.width, r.size.height); |
153 | } |
154 | |
155 | WId Bridge::windowId() const |
156 | { |
157 | return c->window(); |
158 | } |
159 | |
160 | void Bridge::titlebarDblClickOperation() |
161 | { |
162 | workspace()->performWindowOperation(c, options->operationTitlebarDblClick()); |
163 | } |
164 | |
165 | void Bridge::titlebarMouseWheelOperation(int delta) |
166 | { |
167 | c->performMouseCommand(options->operationTitlebarMouseWheel(delta), cursorPos()); |
168 | } |
169 | |
170 | void Bridge::setShade(bool set) |
171 | { |
172 | c->setShade(set ? ShadeNormal : ShadeNone); |
173 | } |
174 | |
175 | int Bridge::currentDesktop() const |
176 | { |
177 | return VirtualDesktopManager::self()->current(); |
178 | } |
179 | |
180 | QWidget* Bridge::initialParentWidget() const |
181 | { |
182 | return NULL; |
183 | } |
184 | |
185 | Qt::WFlags Bridge::initialWFlags() const |
186 | { |
187 | return 0; |
188 | } |
189 | |
190 | QRegion Bridge::unobscuredRegion(const QRegion& r) const |
191 | { |
192 | QRegion reg(r); |
193 | const ToplevelList stacking_order = workspace()->stackingOrder(); |
194 | int pos = stacking_order.indexOf(c); |
195 | ++pos; |
196 | for (; pos < stacking_order.count(); ++pos) { |
197 | Client *client = qobject_cast<Client*>(stacking_order[pos]); |
198 | if (!client) { |
199 | continue; |
200 | } |
201 | if (!client->isShown(true)) |
202 | continue; // these don't obscure the window |
203 | if (c->isOnAllDesktops()) { |
204 | if (!client->isOnCurrentDesktop()) |
205 | continue; |
206 | } else { |
207 | if (!client->isOnDesktop(c->desktop())) |
208 | continue; |
209 | } |
210 | /* the clients all have their mask-regions in local coords |
211 | so we have to translate them to a shared coord system |
212 | we choose ours */ |
213 | int dx = client->x() - c->x(); |
214 | int dy = client->y() - c->y(); |
215 | QRegion creg = client->mask(); |
216 | creg.translate(dx, dy); |
217 | reg -= creg; |
218 | if (reg.isEmpty()) { |
219 | // early out, we are completely obscured |
220 | break; |
221 | } |
222 | } |
223 | return reg; |
224 | } |
225 | |
226 | void Bridge::grabXServer(bool grab) |
227 | { |
228 | if (grab) |
229 | KWin::grabXServer(); |
230 | else |
231 | KWin::ungrabXServer(); |
232 | } |
233 | |
234 | bool Bridge::compositingActive() const |
235 | { |
236 | return Compositor::compositing(); |
237 | } |
238 | |
239 | QRect Bridge::transparentRect() const |
240 | { |
241 | return c->transparentRect().translated(-c->decorationRect().topLeft()); |
242 | } |
243 | |
244 | //BEGIN TABBING |
245 | |
246 | Client *Bridge::clientForId(long id) const |
247 | { |
248 | Client* client = reinterpret_cast<Client*>(id); |
249 | if (!workspace()->hasClient(client)) { |
250 | kWarning(1212) << "****** ARBITRARY CODE EXECUTION ATTEMPT DETECTED ******" << id; |
251 | return 0; |
252 | } |
253 | return client; |
254 | } |
255 | |
256 | int Bridge::tabCount() const |
257 | { |
258 | if (c->tabGroup()) |
259 | return c->tabGroup()->count(); |
260 | return 1; |
261 | } |
262 | |
263 | long Bridge::tabId(int idx) const |
264 | { |
265 | if (c->tabGroup()) |
266 | return tabIdOf(c->tabGroup()->clients().at(idx)); |
267 | return tabIdOf(c); |
268 | } |
269 | |
270 | QIcon Bridge::icon(int idx) const |
271 | { |
272 | if (c->tabGroup()) { |
273 | Client *tabC = c->tabGroup()->clients().at(idx); |
274 | QIcon icon(tabC->icon()); |
275 | icon.addPixmap(tabC->miniIcon()); |
276 | return icon; |
277 | } |
278 | return icon(); |
279 | } |
280 | |
281 | QString Bridge::caption() const |
282 | { |
283 | return c->caption(true, true); |
284 | } |
285 | |
286 | QString Bridge::caption(int idx) const |
287 | { |
288 | if (c->tabGroup()) |
289 | return c->tabGroup()->clients().at(idx)->caption(true, true); |
290 | return c->caption(true, true); |
291 | } |
292 | |
293 | long Bridge::currentTabId() const |
294 | { |
295 | if (c->tabGroup()) |
296 | return tabIdOf(c->tabGroup()->current()); |
297 | return 0; |
298 | } |
299 | |
300 | void Bridge::setCurrentTab(long id) |
301 | { |
302 | if (c->tabGroup()) |
303 | c->tabGroup()->setCurrent(clientForId(id)); |
304 | } |
305 | |
306 | void Bridge::tab_A_before_B(long A, long B) |
307 | { |
308 | if (!B) { |
309 | if (c->tabGroup()) { |
310 | if (Client *a = clientForId(A)) |
311 | a->untab(); |
312 | } |
313 | return; |
314 | } |
315 | |
316 | if (Client *a = clientForId(A)) |
317 | if (Client *b = clientForId(B)) |
318 | if (a != b) |
319 | a->tabBefore(b, true); |
320 | } |
321 | |
322 | void Bridge::tab_A_behind_B(long A, long B) |
323 | { |
324 | if (!B) { |
325 | if (c->tabGroup()) { |
326 | if (Client *a = clientForId(A)) |
327 | a->untab(); |
328 | } |
329 | return; |
330 | } |
331 | |
332 | if (Client *a = clientForId(A)) |
333 | if (Client *b = clientForId(B)) |
334 | if (a != b) |
335 | a->tabBehind(b, true); |
336 | } |
337 | |
338 | |
339 | void Bridge::untab(long id, const QRect& newGeom) |
340 | { |
341 | if (c->tabGroup()) |
342 | if (Client* client = clientForId(id)) |
343 | if (client->untab(newGeom)) { |
344 | if (options->focusPolicyIsReasonable()) |
345 | workspace()->takeActivity(client, ActivityFocus | ActivityRaise, true); |
346 | workspace()->raiseClient(client); |
347 | } |
348 | } |
349 | |
350 | void Bridge::closeTab(long id) |
351 | { |
352 | if (Client* client = clientForId(id)) |
353 | client->closeWindow(); |
354 | } |
355 | |
356 | void Bridge::closeTabGroup() |
357 | { |
358 | if (c->tabGroup()) |
359 | c->tabGroup()->closeAll(); |
360 | } |
361 | |
362 | //END TABBING |
363 | |
364 | KDecoration::WindowOperation Bridge::buttonToWindowOperation(Qt::MouseButtons button) |
365 | { |
366 | return c->mouseButtonToWindowOperation(button); |
367 | } |
368 | |
369 | } // namespace |
370 | |