Changeset View
Changeset View
Standalone View
Standalone View
toplevel.cpp
Show All 11 Lines | |||||
12 | This program is distributed in the hope that it will be useful, | 12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 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/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | | ||||
zzag: Unrelated whitespace change. | |||||
21 | #include "toplevel.h" | 20 | #include "toplevel.h" | ||
22 | 21 | | |||
23 | #ifdef KWIN_BUILD_ACTIVITIES | 22 | #ifdef KWIN_BUILD_ACTIVITIES | ||
24 | #include "activities.h" | 23 | #include "activities.h" | ||
25 | #endif | 24 | #endif | ||
26 | #include "atoms.h" | 25 | #include "atoms.h" | ||
27 | #include "client.h" | 26 | #include "client.h" | ||
28 | #include "client_machine.h" | 27 | #include "client_machine.h" | ||
28 | #include "composite.h" | ||||
29 | #include "effects.h" | 29 | #include "effects.h" | ||
30 | #include "screens.h" | 30 | #include "screens.h" | ||
31 | #include "shadow.h" | 31 | #include "shadow.h" | ||
32 | #include "workspace.h" | ||||
32 | #include "xcbutils.h" | 33 | #include "xcbutils.h" | ||
33 | 34 | | |||
34 | #include <KWayland/Server/surface_interface.h> | 35 | #include <KWayland/Server/surface_interface.h> | ||
35 | 36 | | |||
36 | #include <QDebug> | 37 | #include <QDebug> | ||
37 | 38 | | |||
38 | namespace KWin | 39 | namespace KWin | ||
39 | { | 40 | { | ||
▲ Show 20 Lines • Show All 211 Lines • ▼ Show 20 Line(s) | 251 | if (old_opacity == new_opacity) | |||
251 | return; | 252 | return; | ||
252 | info->setOpacity(static_cast< unsigned long >(new_opacity * 0xffffffff)); | 253 | info->setOpacity(static_cast< unsigned long >(new_opacity * 0xffffffff)); | ||
253 | if (compositing()) { | 254 | if (compositing()) { | ||
254 | addRepaintFull(); | 255 | addRepaintFull(); | ||
255 | emit opacityChanged(this, old_opacity); | 256 | emit opacityChanged(this, old_opacity); | ||
256 | } | 257 | } | ||
257 | } | 258 | } | ||
258 | 259 | | |||
260 | bool Toplevel::setupCompositing() | ||||
261 | { | ||||
262 | if (!compositing()) | ||||
263 | return false; | ||||
264 | | ||||
265 | if (damage_handle != XCB_NONE) | ||||
266 | return false; | ||||
267 | | ||||
268 | if (kwinApp()->operationMode() == Application::OperationModeX11 && !surface()) { | ||||
269 | damage_handle = xcb_generate_id(connection()); | ||||
270 | xcb_damage_create(connection(), damage_handle, frameId(), XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY); | ||||
271 | } | ||||
272 | | ||||
273 | damage_region = QRegion(0, 0, width(), height()); | ||||
274 | effect_window = new EffectWindowImpl(this); | ||||
275 | | ||||
276 | Compositor::self()->scene()->addToplevel(this); | ||||
277 | | ||||
278 | return true; | ||||
279 | } | ||||
280 | | ||||
281 | void Toplevel::finishCompositing(ReleaseReason releaseReason) | ||||
282 | { | ||||
283 | if (kwinApp()->operationMode() == Application::OperationModeX11 && damage_handle == XCB_NONE) | ||||
284 | return; | ||||
285 | if (effect_window->window() == this) { // otherwise it's already passed to Deleted, don't free data | ||||
286 | discardWindowPixmap(); | ||||
287 | delete effect_window; | ||||
288 | } | ||||
289 | | ||||
290 | if (damage_handle != XCB_NONE && | ||||
291 | releaseReason != ReleaseReason::Destroyed) { | ||||
292 | xcb_damage_destroy(connection(), damage_handle); | ||||
293 | } | ||||
294 | | ||||
295 | damage_handle = XCB_NONE; | ||||
296 | damage_region = QRegion(); | ||||
297 | repaints_region = QRegion(); | ||||
298 | effect_window = NULL; | ||||
299 | } | ||||
300 | | ||||
301 | void Toplevel::discardWindowPixmap() | ||||
302 | { | ||||
303 | addDamageFull(); | ||||
304 | if (effectWindow() != NULL && effectWindow()->sceneWindow() != NULL) | ||||
305 | effectWindow()->sceneWindow()->pixmapDiscarded(); | ||||
306 | } | ||||
307 | | ||||
308 | void Toplevel::damageNotifyEvent() | ||||
309 | { | ||||
310 | m_isDamaged = true; | ||||
311 | | ||||
312 | // Note: The rect is supposed to specify the damage extents, | ||||
313 | // but we don't know it at this point. No one who connects | ||||
314 | // to this signal uses the rect however. | ||||
315 | emit damaged(this, QRect()); | ||||
316 | } | ||||
317 | | ||||
318 | bool Toplevel::compositing() const | ||||
319 | { | ||||
320 | if (!Workspace::self()) { | ||||
321 | return false; | ||||
322 | } | ||||
323 | return Workspace::self()->compositing(); | ||||
324 | } | ||||
325 | | ||||
326 | void Client::damageNotifyEvent() | ||||
327 | { | ||||
328 | if (syncRequest.isPending && isResize()) { | ||||
329 | emit damaged(this, QRect()); | ||||
330 | m_isDamaged = true; | ||||
331 | return; | ||||
332 | } | ||||
333 | | ||||
334 | if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead | ||||
335 | if (syncRequest.counter == XCB_NONE) { // cannot detect complete redraw, consider done now | ||||
336 | setReadyForPainting(); | ||||
337 | setupWindowManagementInterface(); | ||||
338 | } | ||||
339 | } | ||||
340 | | ||||
341 | Toplevel::damageNotifyEvent(); | ||||
342 | } | ||||
343 | | ||||
344 | bool Toplevel::resetAndFetchDamage() | ||||
345 | { | ||||
346 | if (!m_isDamaged) | ||||
347 | return false; | ||||
348 | | ||||
349 | if (damage_handle == XCB_NONE) { | ||||
350 | m_isDamaged = false; | ||||
351 | return true; | ||||
352 | } | ||||
353 | | ||||
354 | xcb_connection_t *conn = connection(); | ||||
355 | | ||||
356 | // Create a new region and copy the damage region to it, | ||||
357 | // resetting the damaged state. | ||||
358 | xcb_xfixes_region_t region = xcb_generate_id(conn); | ||||
359 | xcb_xfixes_create_region(conn, region, 0, 0); | ||||
360 | xcb_damage_subtract(conn, damage_handle, 0, region); | ||||
361 | | ||||
362 | // Send a fetch-region request and destroy the region | ||||
363 | m_regionCookie = xcb_xfixes_fetch_region_unchecked(conn, region); | ||||
364 | xcb_xfixes_destroy_region(conn, region); | ||||
365 | | ||||
366 | m_isDamaged = false; | ||||
367 | m_damageReplyPending = true; | ||||
368 | | ||||
369 | return m_damageReplyPending; | ||||
370 | } | ||||
371 | | ||||
372 | void Toplevel::getDamageRegionReply() | ||||
373 | { | ||||
374 | if (!m_damageReplyPending) | ||||
375 | return; | ||||
376 | | ||||
377 | m_damageReplyPending = false; | ||||
378 | | ||||
379 | // Get the fetch-region reply | ||||
380 | xcb_xfixes_fetch_region_reply_t *reply = | ||||
381 | xcb_xfixes_fetch_region_reply(connection(), m_regionCookie, 0); | ||||
382 | | ||||
383 | if (!reply) | ||||
384 | return; | ||||
385 | | ||||
386 | // Convert the reply to a QRegion | ||||
387 | int count = xcb_xfixes_fetch_region_rectangles_length(reply); | ||||
388 | QRegion region; | ||||
389 | | ||||
390 | if (count > 1 && count < 16) { | ||||
391 | xcb_rectangle_t *rects = xcb_xfixes_fetch_region_rectangles(reply); | ||||
392 | | ||||
393 | QVector<QRect> qrects; | ||||
394 | qrects.reserve(count); | ||||
395 | | ||||
396 | for (int i = 0; i < count; i++) | ||||
397 | qrects << QRect(rects[i].x, rects[i].y, rects[i].width, rects[i].height); | ||||
398 | | ||||
399 | region.setRects(qrects.constData(), count); | ||||
400 | } else | ||||
401 | region += QRect(reply->extents.x, reply->extents.y, | ||||
402 | reply->extents.width, reply->extents.height); | ||||
403 | | ||||
404 | damage_region += region; | ||||
405 | repaints_region += region; | ||||
406 | | ||||
407 | free(reply); | ||||
408 | } | ||||
409 | | ||||
410 | void Toplevel::addDamageFull() | ||||
411 | { | ||||
412 | if (!compositing()) | ||||
413 | return; | ||||
414 | | ||||
415 | damage_region = rect(); | ||||
416 | repaints_region |= rect(); | ||||
417 | | ||||
418 | emit damaged(this, rect()); | ||||
419 | } | ||||
420 | | ||||
421 | void Toplevel::resetDamage() | ||||
422 | { | ||||
423 | damage_region = QRegion(); | ||||
424 | } | ||||
425 | | ||||
426 | void Toplevel::addRepaint(const QRect& r) | ||||
427 | { | ||||
428 | if (!compositing()) { | ||||
429 | return; | ||||
430 | } | ||||
431 | repaints_region += r; | ||||
432 | emit needsRepaint(); | ||||
433 | } | ||||
434 | | ||||
435 | void Toplevel::addRepaint(int x, int y, int w, int h) | ||||
436 | { | ||||
437 | QRect r(x, y, w, h); | ||||
438 | addRepaint(r); | ||||
439 | } | ||||
440 | | ||||
441 | void Toplevel::addRepaint(const QRegion& r) | ||||
442 | { | ||||
443 | if (!compositing()) { | ||||
444 | return; | ||||
445 | } | ||||
446 | repaints_region += r; | ||||
447 | emit needsRepaint(); | ||||
448 | } | ||||
449 | | ||||
450 | void Toplevel::addLayerRepaint(const QRect& r) | ||||
451 | { | ||||
452 | if (!compositing()) { | ||||
453 | return; | ||||
454 | } | ||||
455 | layer_repaints_region += r; | ||||
456 | emit needsRepaint(); | ||||
457 | } | ||||
458 | | ||||
459 | void Toplevel::addLayerRepaint(int x, int y, int w, int h) | ||||
460 | { | ||||
461 | QRect r(x, y, w, h); | ||||
462 | addLayerRepaint(r); | ||||
463 | } | ||||
464 | | ||||
465 | void Toplevel::addLayerRepaint(const QRegion& r) | ||||
466 | { | ||||
467 | if (!compositing()) | ||||
468 | return; | ||||
469 | layer_repaints_region += r; | ||||
470 | emit needsRepaint(); | ||||
471 | } | ||||
472 | | ||||
473 | void Toplevel::addRepaintFull() | ||||
474 | { | ||||
475 | repaints_region = visibleRect().translated(-pos()); | ||||
476 | emit needsRepaint(); | ||||
477 | } | ||||
478 | | ||||
479 | void Toplevel::resetRepaints() | ||||
480 | { | ||||
481 | repaints_region = QRegion(); | ||||
482 | layer_repaints_region = QRegion(); | ||||
483 | } | ||||
484 | | ||||
485 | void Toplevel::addWorkspaceRepaint(int x, int y, int w, int h) | ||||
486 | { | ||||
487 | addWorkspaceRepaint(QRect(x, y, w, h)); | ||||
488 | } | ||||
489 | | ||||
490 | void Toplevel::addWorkspaceRepaint(const QRect& r2) | ||||
491 | { | ||||
492 | if (!compositing()) | ||||
493 | return; | ||||
494 | Compositor::self()->addRepaint(r2); | ||||
495 | } | ||||
496 | | ||||
259 | void Toplevel::setReadyForPainting() | 497 | void Toplevel::setReadyForPainting() | ||
260 | { | 498 | { | ||
261 | if (!ready_for_painting) { | 499 | if (!ready_for_painting) { | ||
262 | ready_for_painting = true; | 500 | ready_for_painting = true; | ||
263 | if (compositing()) { | 501 | if (compositing()) { | ||
264 | addRepaintFull(); | 502 | addRepaintFull(); | ||
265 | emit windowShown(this); | 503 | emit windowShown(this); | ||
266 | if (auto *cl = dynamic_cast<AbstractClient*>(this)) { | 504 | if (auto *cl = dynamic_cast<AbstractClient*>(this)) { | ||
▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines |
Unrelated whitespace change.