Changeset View
Changeset View
Standalone View
Standalone View
effects/presentwindows/presentwindows.cpp
Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 51 | PresentWindowsEffect::PresentWindowsEffect() | |||
---|---|---|---|---|---|
55 | , m_decalOpacity(0.0) | 55 | , m_decalOpacity(0.0) | ||
56 | , m_hasKeyboardGrab(false) | 56 | , m_hasKeyboardGrab(false) | ||
57 | , m_mode(ModeCurrentDesktop) | 57 | , m_mode(ModeCurrentDesktop) | ||
58 | , m_managerWindow(nullptr) | 58 | , m_managerWindow(nullptr) | ||
59 | , m_needInitialSelection(false) | 59 | , m_needInitialSelection(false) | ||
60 | , m_highlightedWindow(nullptr) | 60 | , m_highlightedWindow(nullptr) | ||
61 | , m_filterFrame(nullptr) | 61 | , m_filterFrame(nullptr) | ||
62 | , m_closeView(nullptr) | 62 | , m_closeView(nullptr) | ||
63 | , m_closeWindow(nullptr) | | |||
64 | , m_exposeAction(new QAction(this)) | 63 | , m_exposeAction(new QAction(this)) | ||
65 | , m_exposeAllAction(new QAction(this)) | 64 | , m_exposeAllAction(new QAction(this)) | ||
66 | , m_exposeClassAction(new QAction(this)) | 65 | , m_exposeClassAction(new QAction(this)) | ||
67 | { | 66 | { | ||
68 | initConfig<PresentWindowsConfig>(); | 67 | initConfig<PresentWindowsConfig>(); | ||
69 | auto announceSupportProperties = [this] { | 68 | auto announceSupportProperties = [this] { | ||
70 | m_atomDesktop = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_DESKTOP", this); | 69 | m_atomDesktop = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_DESKTOP", this); | ||
71 | m_atomWindows = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_GROUP", this); | 70 | m_atomWindows = effects->announceSupportProperty("_KDE_PRESENT_WINDOWS_GROUP", this); | ||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Line(s) | 125 | { | |||
147 | } | 146 | } | ||
148 | m_layoutMode = PresentWindowsConfig::layoutMode(); | 147 | m_layoutMode = PresentWindowsConfig::layoutMode(); | ||
149 | m_showCaptions = PresentWindowsConfig::drawWindowCaptions(); | 148 | m_showCaptions = PresentWindowsConfig::drawWindowCaptions(); | ||
150 | m_showIcons = PresentWindowsConfig::drawWindowIcons(); | 149 | m_showIcons = PresentWindowsConfig::drawWindowIcons(); | ||
151 | m_doNotCloseWindows = !PresentWindowsConfig::allowClosingWindows(); | 150 | m_doNotCloseWindows = !PresentWindowsConfig::allowClosingWindows(); | ||
152 | if (m_doNotCloseWindows) { | 151 | if (m_doNotCloseWindows) { | ||
153 | delete m_closeView; | 152 | delete m_closeView; | ||
154 | m_closeView = nullptr; | 153 | m_closeView = nullptr; | ||
155 | m_closeWindow = nullptr; | | |||
156 | } | 154 | } | ||
157 | m_ignoreMinimized = PresentWindowsConfig::ignoreMinimized(); | 155 | m_ignoreMinimized = PresentWindowsConfig::ignoreMinimized(); | ||
158 | m_accuracy = PresentWindowsConfig::accuracy() * 20; | 156 | m_accuracy = PresentWindowsConfig::accuracy() * 20; | ||
159 | m_fillGaps = PresentWindowsConfig::fillGaps(); | 157 | m_fillGaps = PresentWindowsConfig::fillGaps(); | ||
160 | m_fadeDuration = double(animationTime(150)); | 158 | m_fadeDuration = double(animationTime(150)); | ||
161 | m_showPanel = PresentWindowsConfig::showPanel(); | 159 | m_showPanel = PresentWindowsConfig::showPanel(); | ||
162 | m_leftButtonWindow = (WindowMouseAction)PresentWindowsConfig::leftButtonWindow(); | 160 | m_leftButtonWindow = (WindowMouseAction)PresentWindowsConfig::leftButtonWindow(); | ||
163 | m_middleButtonWindow = (WindowMouseAction)PresentWindowsConfig::middleButtonWindow(); | 161 | m_middleButtonWindow = (WindowMouseAction)PresentWindowsConfig::middleButtonWindow(); | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | |||||
223 | 221 | | |||
224 | void PresentWindowsEffect::paintScreen(int mask, QRegion region, ScreenPaintData &data) | 222 | void PresentWindowsEffect::paintScreen(int mask, QRegion region, ScreenPaintData &data) | ||
225 | { | 223 | { | ||
226 | effects->paintScreen(mask, region, data); | 224 | effects->paintScreen(mask, region, data); | ||
227 | 225 | | |||
228 | // Display the filter box | 226 | // Display the filter box | ||
229 | if (!m_windowFilter.isEmpty()) | 227 | if (!m_windowFilter.isEmpty()) | ||
230 | m_filterFrame->render(region); | 228 | m_filterFrame->render(region); | ||
229 | | ||||
230 | if (m_closeView) | ||||
231 | effects->renderEffectQuickView(m_closeView); | ||||
231 | } | 232 | } | ||
232 | 233 | | |||
233 | void PresentWindowsEffect::postPaintScreen() | 234 | void PresentWindowsEffect::postPaintScreen() | ||
234 | { | 235 | { | ||
235 | if (m_motionManager.areWindowsMoving()) | 236 | if (m_motionManager.areWindowsMoving()) | ||
236 | effects->addRepaintFull(); | 237 | effects->addRepaintFull(); | ||
237 | else if (!m_activated && m_motionManager.managingWindows() && !(m_closeWindow && m_closeView->isVisible())) { | 238 | else if (!m_activated && m_motionManager.managingWindows() && !(m_closeView && m_closeView->isVisible())) { | ||
zzag: > m_closeView->isVisible()
This can potentially segfault if the user unchecked "Provide… | |||||
238 | // We have finished moving them back, stop processing | 239 | // We have finished moving them back, stop processing | ||
239 | m_motionManager.unmanageAll(); | 240 | m_motionManager.unmanageAll(); | ||
240 | 241 | | |||
241 | DataHash::iterator i = m_windowData.begin(); | 242 | DataHash::iterator i = m_windowData.begin(); | ||
242 | while (i != m_windowData.end()) { | 243 | while (i != m_windowData.end()) { | ||
243 | delete i.value().textFrame; | 244 | delete i.value().textFrame; | ||
244 | delete i.value().iconFrame; | 245 | delete i.value().iconFrame; | ||
245 | ++i; | 246 | ++i; | ||
Show All 30 Lines | |||||
276 | 277 | | |||
277 | //----------------------------------------------------------------------------- | 278 | //----------------------------------------------------------------------------- | ||
278 | // Window painting | 279 | // Window painting | ||
279 | 280 | | |||
280 | void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) | 281 | void PresentWindowsEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time) | ||
281 | { | 282 | { | ||
282 | // TODO: We should also check to see if any windows are fading just in case fading takes longer | 283 | // TODO: We should also check to see if any windows are fading just in case fading takes longer | ||
283 | // than moving the windows when the effect is deactivated. | 284 | // than moving the windows when the effect is deactivated. | ||
284 | if (m_activated || m_motionManager.areWindowsMoving() || m_closeWindow) { | 285 | if (m_activated || m_motionManager.areWindowsMoving() || m_closeView) { | ||
285 | DataHash::iterator winData = m_windowData.find(w); | 286 | DataHash::iterator winData = m_windowData.find(w); | ||
286 | if (winData == m_windowData.end()) { | 287 | if (winData == m_windowData.end()) { | ||
287 | effects->prePaintWindow(w, data, time); | 288 | effects->prePaintWindow(w, data, time); | ||
288 | return; | 289 | return; | ||
289 | } | 290 | } | ||
290 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always | 291 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); // Display always | ||
291 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP); | 292 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP); | ||
292 | 293 | | |||
Show All 11 Lines | 304 | if (winData->opacity <= 0.0) { | |||
304 | // don't disable painting for panels if show panel is set | 305 | // don't disable painting for panels if show panel is set | ||
305 | if (!(m_showPanel && w->isDock())) | 306 | if (!(m_showPanel && w->isDock())) | ||
306 | w->disablePainting(EffectWindow::PAINT_DISABLED); | 307 | w->disablePainting(EffectWindow::PAINT_DISABLED); | ||
307 | } else if (winData->opacity != 1.0) | 308 | } else if (winData->opacity != 1.0) | ||
308 | data.setTranslucent(); | 309 | data.setTranslucent(); | ||
309 | 310 | | |||
310 | const bool isInMotion = m_motionManager.isManaging(w); | 311 | const bool isInMotion = m_motionManager.isManaging(w); | ||
311 | // Calculate window's brightness | 312 | // Calculate window's brightness | ||
312 | if (w == m_highlightedWindow || w == m_closeWindow || !m_activated) | 313 | if (w == m_highlightedWindow || !m_activated) | ||
313 | winData->highlight = qMin(1.0, winData->highlight + time / m_fadeDuration); | 314 | winData->highlight = qMin(1.0, winData->highlight + time / m_fadeDuration); | ||
314 | else if (!isInMotion && w->isDesktop()) | 315 | else if (!isInMotion && w->isDesktop()) | ||
315 | winData->highlight = 0.3; | 316 | winData->highlight = 0.3; | ||
316 | else | 317 | else | ||
317 | winData->highlight = qMax(0.0, winData->highlight - time / m_fadeDuration); | 318 | winData->highlight = qMax(0.0, winData->highlight - time / m_fadeDuration); | ||
318 | 319 | | |||
319 | // Closed windows | 320 | // Closed windows | ||
320 | if (winData->deleted) { | 321 | if (winData->deleted) { | ||
321 | data.setTranslucent(); | 322 | data.setTranslucent(); | ||
322 | if (winData->opacity <= 0.0 && winData->referenced) { | 323 | if (winData->opacity <= 0.0 && winData->referenced) { | ||
323 | // it's possible that another effect has referenced the window | 324 | // it's possible that another effect has referenced the window | ||
324 | // we have to keep the window in the list to prevent flickering | 325 | // we have to keep the window in the list to prevent flickering | ||
325 | winData->referenced = false; | 326 | winData->referenced = false; | ||
326 | w->unrefWindow(); | 327 | w->unrefWindow(); | ||
327 | if (w == m_closeWindow) { | | |||
328 | m_closeWindow = nullptr; | | |||
329 | } | | |||
330 | } else | 328 | } else | ||
331 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE); | 329 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE); | ||
332 | } | 330 | } | ||
333 | 331 | | |||
334 | // desktop windows on other desktops (Plasma activity per desktop) should not be painted | 332 | // desktop windows on other desktops (Plasma activity per desktop) should not be painted | ||
335 | if (w->isDesktop() && !w->isOnCurrentDesktop()) | 333 | if (w->isDesktop() && !w->isOnCurrentDesktop()) | ||
336 | w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP); | 334 | w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP); | ||
337 | 335 | | |||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Line(s) | 423 | if (m_showCaptions) { | |||
428 | winData->textFrame->setPosition(point); | 426 | winData->textFrame->setPosition(point); | ||
429 | if (effects->compositingType() == KWin::OpenGL2Compositing && data.shader) { | 427 | if (effects->compositingType() == KWin::OpenGL2Compositing && data.shader) { | ||
430 | const float a = 0.9 * data.opacity() * m_decalOpacity * 0.75; | 428 | const float a = 0.9 * data.opacity() * m_decalOpacity * 0.75; | ||
431 | data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a)); | 429 | data.shader->setUniform(GLShader::ModulationConstant, QVector4D(a, a, a, a)); | ||
432 | } | 430 | } | ||
433 | winData->textFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75); | 431 | winData->textFrame->render(region, 0.9 * data.opacity() * m_decalOpacity, 0.75); | ||
434 | } | 432 | } | ||
435 | } else { | 433 | } else { | ||
436 | if (w == m_closeWindow && m_closeView && !m_closeView->isVisible()) { | | |||
437 | data.setOpacity(0); | | |||
438 | } | | |||
439 | effects->paintWindow(w, mask, region, data); | 434 | effects->paintWindow(w, mask, region, data); | ||
440 | } | 435 | } | ||
441 | } else | 436 | } else | ||
442 | effects->paintWindow(w, mask, region, data); | 437 | effects->paintWindow(w, mask, region, data); | ||
443 | } | 438 | } | ||
444 | 439 | | |||
445 | //----------------------------------------------------------------------------- | 440 | //----------------------------------------------------------------------------- | ||
446 | // User interaction | 441 | // User interaction | ||
Show All 14 Lines | 444 | { | |||
461 | winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false); | 456 | winData->iconFrame = effects->effectFrame(EffectFrameUnstyled, false); | ||
462 | winData->iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom); | 457 | winData->iconFrame->setAlignment(Qt::AlignRight | Qt::AlignBottom); | ||
463 | winData->iconFrame->setIcon(w->icon()); | 458 | winData->iconFrame->setIcon(w->icon()); | ||
464 | winData->iconFrame->setIconSize(QSize(32, 32)); | 459 | winData->iconFrame->setIconSize(QSize(32, 32)); | ||
465 | if (isSelectableWindow(w)) { | 460 | if (isSelectableWindow(w)) { | ||
466 | m_motionManager.manage(w); | 461 | m_motionManager.manage(w); | ||
467 | rearrangeWindows(); | 462 | rearrangeWindows(); | ||
468 | } | 463 | } | ||
469 | if (m_closeView && w == effects->findWindow(m_closeView->winId())) { | | |||
470 | if (m_closeWindow != w) { | | |||
471 | DataHash::iterator winDataIt = m_windowData.find(m_closeWindow); | | |||
472 | if (winDataIt != m_windowData.end()) { | | |||
473 | if (winDataIt->referenced) { | | |||
474 | m_closeWindow->unrefWindow(); | | |||
475 | } | | |||
476 | m_windowData.erase(winDataIt); | | |||
477 | } | | |||
478 | } | | |||
479 | winData->visible = true; | | |||
480 | winData->highlight = 1.0; | | |||
481 | m_closeWindow = w; | | |||
482 | w->setData(WindowForceBlurRole, QVariant(true)); | | |||
483 | w->setData(WindowForceBackgroundContrastRole, QVariant(true)); | | |||
484 | } | | |||
485 | } | 464 | } | ||
486 | 465 | | |||
487 | void PresentWindowsEffect::slotWindowClosed(EffectWindow *w) | 466 | void PresentWindowsEffect::slotWindowClosed(EffectWindow *w) | ||
488 | { | 467 | { | ||
489 | if (m_managerWindow == w) | 468 | if (m_managerWindow == w) | ||
490 | m_managerWindow = nullptr; | 469 | m_managerWindow = nullptr; | ||
491 | DataHash::iterator winData = m_windowData.find(w); | 470 | DataHash::iterator winData = m_windowData.find(w); | ||
492 | if (winData == m_windowData.end()) | 471 | if (winData == m_windowData.end()) | ||
493 | return; | 472 | return; | ||
494 | winData->deleted = true; | 473 | winData->deleted = true; | ||
495 | if (!winData->referenced) { | 474 | if (!winData->referenced) { | ||
496 | winData->referenced = true; | 475 | winData->referenced = true; | ||
497 | w->refWindow(); | 476 | w->refWindow(); | ||
498 | } | 477 | } | ||
499 | if (m_highlightedWindow == w) | 478 | if (m_highlightedWindow == w) | ||
500 | setHighlightedWindow(findFirstWindow()); | 479 | setHighlightedWindow(findFirstWindow()); | ||
501 | if (m_closeWindow == w) { | | |||
502 | return; // don't rearrange, get's nulled when unref'd | | |||
503 | } | | |||
504 | rearrangeWindows(); | 480 | rearrangeWindows(); | ||
505 | 481 | | |||
506 | foreach (EffectWindow *w, m_motionManager.managedWindows()) { | 482 | foreach (EffectWindow *w, m_motionManager.managedWindows()) { | ||
507 | winData = m_windowData.find(w); | 483 | winData = m_windowData.find(w); | ||
508 | if (winData != m_windowData.end() && !winData->deleted) | 484 | if (winData != m_windowData.end() && !winData->deleted) | ||
509 | return; // found one that is not deleted? then we go on | 485 | return; // found one that is not deleted? then we go on | ||
510 | } | 486 | } | ||
511 | setActive(false); //else no need to keep this open | 487 | setActive(false); //else no need to keep this open | ||
Show All 12 Lines | |||||
524 | 500 | | |||
525 | void PresentWindowsEffect::slotWindowGeometryShapeChanged(EffectWindow* w, const QRect& old) | 501 | void PresentWindowsEffect::slotWindowGeometryShapeChanged(EffectWindow* w, const QRect& old) | ||
526 | { | 502 | { | ||
527 | Q_UNUSED(old) | 503 | Q_UNUSED(old) | ||
528 | if (!m_activated) | 504 | if (!m_activated) | ||
529 | return; | 505 | return; | ||
530 | if (!m_windowData.contains(w)) | 506 | if (!m_windowData.contains(w)) | ||
531 | return; | 507 | return; | ||
532 | if (w != m_closeWindow) | | |||
533 | rearrangeWindows(); | 508 | rearrangeWindows(); | ||
zzag: Shouldn't it stay? | |||||
534 | } | 509 | } | ||
535 | 510 | | |||
536 | bool PresentWindowsEffect::borderActivated(ElectricBorder border) | 511 | bool PresentWindowsEffect::borderActivated(ElectricBorder border) | ||
537 | { | 512 | { | ||
538 | int mode = 0; | 513 | int mode = 0; | ||
539 | if (m_borderActivate.contains(border)) | 514 | if (m_borderActivate.contains(border)) | ||
540 | mode |= 1; | 515 | mode |= 1; | ||
541 | else if (m_borderActivateAll.contains(border)) | 516 | else if (m_borderActivateAll.contains(border)) | ||
Show All 22 Lines | 537 | { | |||
564 | if (!me) { | 539 | if (!me) { | ||
565 | return; | 540 | return; | ||
566 | } | 541 | } | ||
567 | if (m_closeView) { | 542 | if (m_closeView) { | ||
568 | const bool contains = m_closeView->geometry().contains(me->pos()); | 543 | const bool contains = m_closeView->geometry().contains(me->pos()); | ||
569 | if (!m_closeView->isVisible() && contains) { | 544 | if (!m_closeView->isVisible() && contains) { | ||
570 | updateCloseWindow(); | 545 | updateCloseWindow(); | ||
571 | } | 546 | } | ||
572 | if (m_closeView->isVisible()) { | 547 | m_closeView->forwardMouseEvent(e); | ||
573 | const QPoint widgetPos = m_closeView->mapFromGlobal(me->pos()); | | |||
574 | // const QPointF scenePos = m_closeView->mapToScene(widgetPos); | | |||
575 | QMouseEvent event(me->type(), widgetPos, me->pos(), me->button(), me->buttons(), me->modifiers()); | | |||
576 | m_closeView->windowInputMouseEvent(&event); | | |||
577 | if (contains) { | | |||
578 | // filter out | | |||
579 | return; | | |||
580 | } | | |||
581 | } | | |||
582 | } | 548 | } | ||
583 | inputEventUpdate(me->pos(), me->type(), me->button()); | 549 | inputEventUpdate(me->pos(), me->type(), me->button()); | ||
584 | } | 550 | } | ||
585 | 551 | | |||
586 | void PresentWindowsEffect::inputEventUpdate(const QPoint &pos, QEvent::Type type, Qt::MouseButton button) | 552 | void PresentWindowsEffect::inputEventUpdate(const QPoint &pos, QEvent::Type type, Qt::MouseButton button) | ||
587 | { | 553 | { | ||
588 | // Which window are we hovering over? Always trigger as we don't always get move events before clicking | 554 | // Which window are we hovering over? Always trigger as we don't always get move events before clicking | ||
589 | // We cannot use m_motionManager.windowAtPoint() as the window might not be visible | 555 | // We cannot use m_motionManager.windowAtPoint() as the window might not be visible | ||
▲ Show 20 Lines • Show All 944 Lines • ▼ Show 20 Line(s) | 1498 | if (m_activated) { | |||
1534 | m_needInitialSelection = true; | 1500 | m_needInitialSelection = true; | ||
1535 | m_closeButtonCorner = (Qt::Corner)effects->kwinOption(KWin::CloseButtonCorner).toInt(); | 1501 | m_closeButtonCorner = (Qt::Corner)effects->kwinOption(KWin::CloseButtonCorner).toInt(); | ||
1536 | m_decalOpacity = 0.0; | 1502 | m_decalOpacity = 0.0; | ||
1537 | m_highlightedWindow = nullptr; | 1503 | m_highlightedWindow = nullptr; | ||
1538 | m_windowFilter.clear(); | 1504 | m_windowFilter.clear(); | ||
1539 | 1505 | | |||
1540 | if (!(m_doNotCloseWindows || m_closeView)) { | 1506 | if (!(m_doNotCloseWindows || m_closeView)) { | ||
1541 | m_closeView = new CloseWindowView(); | 1507 | m_closeView = new CloseWindowView(); | ||
1508 | connect(m_closeView, &EffectQuickView::repaintNeeded, this, []() { | ||||
1509 | effects->addRepaintFull(); | ||||
1510 | }); | ||||
1542 | connect(m_closeView, &CloseWindowView::requestClose, this, &PresentWindowsEffect::closeWindow); | 1511 | connect(m_closeView, &CloseWindowView::requestClose, this, &PresentWindowsEffect::closeWindow); | ||
1543 | } | 1512 | } | ||
1544 | 1513 | | |||
1545 | // Add every single window to m_windowData (Just calling [w] creates it) | 1514 | // Add every single window to m_windowData (Just calling [w] creates it) | ||
1546 | foreach (EffectWindow * w, effects->stackingOrder()) { | 1515 | foreach (EffectWindow * w, effects->stackingOrder()) { | ||
1547 | DataHash::iterator winData; | 1516 | DataHash::iterator winData; | ||
1548 | if ((winData = m_windowData.find(w)) != m_windowData.end()) { | 1517 | if ((winData = m_windowData.find(w)) != m_windowData.end()) { | ||
1549 | winData->visible = isVisibleWindow(w); | 1518 | winData->visible = isVisibleWindow(w); | ||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Line(s) | 1642 | { | |||
1676 | if (w->isSpecialWindow() || w->isUtility()) | 1645 | if (w->isSpecialWindow() || w->isUtility()) | ||
1677 | return false; | 1646 | return false; | ||
1678 | if (w->isDeleted()) | 1647 | if (w->isDeleted()) | ||
1679 | return false; | 1648 | return false; | ||
1680 | if (!w->acceptsFocus()) | 1649 | if (!w->acceptsFocus()) | ||
1681 | return false; | 1650 | return false; | ||
1682 | if (w->isSkipSwitcher()) | 1651 | if (w->isSkipSwitcher()) | ||
1683 | return false; | 1652 | return false; | ||
1684 | if (m_closeView && w == effects->findWindow(m_closeView->winId())) | | |||
1685 | return false; | | |||
1686 | if (m_ignoreMinimized && w->isMinimized()) | 1653 | if (m_ignoreMinimized && w->isMinimized()) | ||
1687 | return false; | 1654 | return false; | ||
1688 | switch(m_mode) { | 1655 | switch(m_mode) { | ||
1689 | default: | 1656 | default: | ||
1690 | case ModeAllDesktops: | 1657 | case ModeAllDesktops: | ||
1691 | return true; | 1658 | return true; | ||
1692 | case ModeCurrentDesktop: | 1659 | case ModeCurrentDesktop: | ||
1693 | return w->isOnCurrentDesktop(); | 1660 | return w->isOnCurrentDesktop(); | ||
1694 | case ModeSelectedDesktop: | 1661 | case ModeSelectedDesktop: | ||
1695 | return w->isOnDesktop(m_desktop); | 1662 | return w->isOnDesktop(m_desktop); | ||
1696 | case ModeWindowGroup: | 1663 | case ModeWindowGroup: | ||
1697 | return m_selectedWindows.contains(w); | 1664 | return m_selectedWindows.contains(w); | ||
1698 | case ModeWindowClass: | 1665 | case ModeWindowClass: | ||
1699 | return m_class == w->windowClass(); | 1666 | return m_class == w->windowClass(); | ||
1700 | } | 1667 | } | ||
1701 | } | 1668 | } | ||
1702 | 1669 | | |||
1703 | bool PresentWindowsEffect::isVisibleWindow(EffectWindow *w) | 1670 | bool PresentWindowsEffect::isVisibleWindow(EffectWindow *w) | ||
1704 | { | 1671 | { | ||
1705 | if (w->isDesktop() || w == m_closeWindow) | 1672 | if (w->isDesktop()) | ||
1706 | return true; | 1673 | return true; | ||
1707 | return isSelectableWindow(w); | 1674 | return isSelectableWindow(w); | ||
1708 | } | 1675 | } | ||
1709 | 1676 | | |||
1710 | void PresentWindowsEffect::setHighlightedWindow(EffectWindow *w) | 1677 | void PresentWindowsEffect::setHighlightedWindow(EffectWindow *w) | ||
1711 | { | 1678 | { | ||
1712 | if (w == m_highlightedWindow || (w != nullptr && !m_motionManager.isManaging(w))) | 1679 | if (w == m_highlightedWindow || (w != nullptr && !m_motionManager.isManaging(w))) | ||
1713 | return; | 1680 | return; | ||
1714 | 1681 | | |||
1715 | if (m_closeView) | 1682 | if (m_closeView) | ||
1716 | m_closeView->hide(); | 1683 | m_closeView->hide(); | ||
1717 | if (m_highlightedWindow) { | 1684 | if (m_highlightedWindow) { | ||
1718 | effects->setElevatedWindow(m_highlightedWindow, false); | 1685 | effects->setElevatedWindow(m_highlightedWindow, false); | ||
1719 | m_highlightedWindow->addRepaintFull(); // Trigger the first repaint | 1686 | m_highlightedWindow->addRepaintFull(); // Trigger the first repaint | ||
1720 | } | 1687 | } | ||
1721 | m_highlightedWindow = w; | 1688 | m_highlightedWindow = w; | ||
1722 | if (m_highlightedWindow) { | 1689 | if (m_highlightedWindow) { | ||
1723 | effects->setElevatedWindow(m_highlightedWindow, true); | 1690 | effects->setElevatedWindow(m_highlightedWindow, true); | ||
1724 | m_highlightedWindow->addRepaintFull(); // Trigger the first repaint | 1691 | m_highlightedWindow->addRepaintFull(); // Trigger the first repaint | ||
1725 | } | 1692 | } | ||
1726 | 1693 | | |||
1727 | updateCloseWindow(); | 1694 | updateCloseWindow(); | ||
1728 | } | 1695 | } | ||
1729 | 1696 | | |||
1730 | void PresentWindowsEffect::elevateCloseWindow() | | |||
1731 | { | | |||
1732 | if (!m_closeView || !m_activated) | | |||
1733 | return; | | |||
1734 | if (EffectWindow *cw = effects->findWindow(m_closeView->winId())) | | |||
1735 | effects->setElevatedWindow(cw, true); | | |||
1736 | } | | |||
1737 | | ||||
1738 | void PresentWindowsEffect::updateCloseWindow() | 1697 | void PresentWindowsEffect::updateCloseWindow() | ||
1739 | { | 1698 | { | ||
1740 | if (!m_closeView || m_doNotCloseWindows) | 1699 | if (!m_closeView || m_doNotCloseWindows) | ||
1741 | return; | 1700 | return; | ||
1742 | 1701 | | |||
1743 | if (!m_activated || !m_highlightedWindow || m_highlightedWindow->isDesktop()) { | 1702 | if (!m_activated || !m_highlightedWindow || m_highlightedWindow->isDesktop()) { | ||
1744 | m_closeView->hide(); | 1703 | m_closeView->hide(); | ||
1745 | return; | 1704 | return; | ||
1746 | } | 1705 | } | ||
1747 | if (m_closeView->isVisible()) | 1706 | if (m_closeView->isVisible()) | ||
1748 | return; | 1707 | return; | ||
1749 | 1708 | | |||
1750 | const QRectF rect(m_motionManager.targetGeometry(m_highlightedWindow)); | 1709 | const QRectF rect(m_motionManager.targetGeometry(m_highlightedWindow)); | ||
1751 | if (2*m_closeView->width() > rect.width() && 2*m_closeView->height() > rect.height()) { | 1710 | if (2*m_closeView->geometry().width() > rect.width() && 2*m_closeView->geometry().height() > rect.height()) { | ||
1752 | // not for tiny windows (eg. with many windows) - they might become unselectable | 1711 | // not for tiny windows (eg. with many windows) - they might become unselectable | ||
1753 | m_closeView->hide(); | 1712 | m_closeView->hide(); | ||
1754 | return; | 1713 | return; | ||
1755 | } | 1714 | } | ||
1756 | QRect cvr(QPoint(0,0), m_closeView->size()); | 1715 | QRect cvr(QPoint(0,0), m_closeView->size()); | ||
1757 | switch (m_closeButtonCorner) | 1716 | switch (m_closeButtonCorner) | ||
1758 | { | 1717 | { | ||
1759 | case Qt::TopLeftCorner: | 1718 | case Qt::TopLeftCorner: | ||
1760 | default: | 1719 | default: | ||
1761 | cvr.moveTopLeft(rect.topLeft().toPoint()); break; | 1720 | cvr.moveTopLeft(rect.topLeft().toPoint()); break; | ||
1762 | case Qt::TopRightCorner: | 1721 | case Qt::TopRightCorner: | ||
1763 | cvr.moveTopRight(rect.topRight().toPoint()); break; | 1722 | cvr.moveTopRight(rect.topRight().toPoint()); break; | ||
1764 | case Qt::BottomLeftCorner: | 1723 | case Qt::BottomLeftCorner: | ||
1765 | cvr.moveBottomLeft(rect.bottomLeft().toPoint()); break; | 1724 | cvr.moveBottomLeft(rect.bottomLeft().toPoint()); break; | ||
1766 | case Qt::BottomRightCorner: | 1725 | case Qt::BottomRightCorner: | ||
1767 | cvr.moveBottomRight(rect.bottomRight().toPoint()); break; | 1726 | cvr.moveBottomRight(rect.bottomRight().toPoint()); break; | ||
1768 | } | 1727 | } | ||
1769 | m_closeView->setGeometry(cvr); | 1728 | m_closeView->setGeometry(cvr); | ||
1770 | if (rect.contains(effects->cursorPos())) { | 1729 | if (rect.contains(effects->cursorPos())) { | ||
1771 | m_closeView->show(); | 1730 | m_closeView->show(); | ||
1772 | m_closeView->disarm(); | 1731 | m_closeView->disarm(); | ||
1773 | // to wait for the next event cycle (or more if the show takes more time) | | |||
1774 | // TODO: make the closeWindow a graphicsviewitem? why should there be an extra scene to be used in an exiting scene?? | | |||
1775 | QTimer::singleShot(50, this, SLOT(elevateCloseWindow())); | | |||
1776 | } | 1732 | } | ||
1777 | else | 1733 | else | ||
1778 | m_closeView->hide(); | 1734 | m_closeView->hide(); | ||
1779 | } | 1735 | } | ||
1780 | 1736 | | |||
1781 | void PresentWindowsEffect::closeWindow() | 1737 | void PresentWindowsEffect::closeWindow() | ||
1782 | { | 1738 | { | ||
1783 | if (m_highlightedWindow) | 1739 | if (m_highlightedWindow) | ||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Line(s) | |||||
1973 | { | 1929 | { | ||
1974 | m_gridSizes.clear(); | 1930 | m_gridSizes.clear(); | ||
1975 | for (int i = 0; i < effects->numScreens(); ++i) { | 1931 | for (int i = 0; i < effects->numScreens(); ++i) { | ||
1976 | m_gridSizes.append(GridSize()); | 1932 | m_gridSizes.append(GridSize()); | ||
1977 | } | 1933 | } | ||
1978 | rearrangeWindows(); | 1934 | rearrangeWindows(); | ||
1979 | } | 1935 | } | ||
1980 | 1936 | | |||
1981 | /************************************************ | | |||
1982 | * CloseWindowView | | |||
1983 | ************************************************/ | | |||
1984 | CloseWindowView::CloseWindowView(QObject *parent) | 1937 | CloseWindowView::CloseWindowView(QObject *parent) | ||
1985 | : QObject(parent) | 1938 | : EffectQuickScene(parent) | ||
1986 | , m_armTimer(new QElapsedTimer()) | 1939 | , m_armTimer(new QElapsedTimer()) | ||
1987 | , m_window(new QQuickView()) | 1940 | { | ||
1988 | , m_visible(false) | 1941 | setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml")))); | ||
1989 | , m_posIsValid(false) | 1942 | if (QQuickItem *item = rootItem()) { | ||
1990 | { | 1943 | connect(item, SIGNAL(clicked()), this, SLOT(clicked())); | ||
1991 | m_window->setFlags(Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint); | 1944 | setGeometry(QRect(QPoint(), QSize(item->implicitWidth(), item->implicitHeight()))); | ||
1992 | m_window->setColor(Qt::transparent); | | |||
1993 | | ||||
1994 | m_window->setSource(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/presentwindows/main.qml")))); | | |||
1995 | if (QObject *item = m_window->rootObject()->findChild<QObject*>(QStringLiteral("closeButton"))) { | | |||
1996 | connect(item, SIGNAL(clicked()), SIGNAL(requestClose())); | | |||
1997 | } | 1945 | } | ||
1998 | | ||||
1999 | m_armTimer->restart(); | 1946 | m_armTimer->restart(); | ||
2000 | } | 1947 | } | ||
2001 | 1948 | | |||
2002 | void CloseWindowView::windowInputMouseEvent(QMouseEvent *e) | 1949 | void CloseWindowView::clicked() | ||
2003 | { | 1950 | { | ||
2004 | if (e->type() == QEvent::MouseMove) { | | |||
2005 | qApp->sendEvent(m_window.data(), e); | | |||
2006 | } else if (!m_armTimer->hasExpired(350)) { | | |||
2007 | // 50ms until the window is elevated (seen!) and 300ms more to be "realized" by the user. | 1951 | // 50ms until the window is elevated (seen!) and 300ms more to be "realized" by the user. | ||
2008 | return; | 1952 | if (m_armTimer->hasExpired(350)) { | ||
1953 | emit requestClose(); | ||||
2009 | } | 1954 | } | ||
2010 | qApp->sendEvent(m_window.data(), e); | | |||
2011 | } | 1955 | } | ||
2012 | 1956 | | |||
2013 | void CloseWindowView::disarm() | 1957 | void CloseWindowView::disarm() | ||
2014 | { | 1958 | { | ||
2015 | m_armTimer->restart(); | 1959 | m_armTimer->restart(); | ||
2016 | } | 1960 | } | ||
2017 | 1961 | | |||
2018 | bool CloseWindowView::isVisible() const | | |||
2019 | { | | |||
2020 | return m_visible; | | |||
2021 | } | | |||
2022 | | ||||
2023 | void CloseWindowView::show() | | |||
2024 | { | | |||
2025 | if (!m_visible && m_posIsValid) { | | |||
2026 | m_window->setPosition(m_pos); | | |||
2027 | m_posIsValid = false; | | |||
2028 | } | | |||
2029 | m_visible = true; | | |||
2030 | m_window->show(); | | |||
2031 | } | | |||
2032 | | ||||
2033 | void CloseWindowView::hide() | | |||
2034 | { | | |||
2035 | if (!m_posIsValid) { | | |||
2036 | m_pos = m_window->position(); | | |||
2037 | m_posIsValid = true; | | |||
2038 | m_window->setPosition(-m_window->width(), -m_window->height()); | | |||
2039 | } | | |||
2040 | m_visible = false; | | |||
2041 | QEvent event(QEvent::Leave); | | |||
2042 | qApp->sendEvent(m_window.data(), &event); | | |||
2043 | } | | |||
2044 | | ||||
2045 | #define DELEGATE(type, name) \ | | |||
2046 | type CloseWindowView::name() const \ | | |||
2047 | { \ | | |||
2048 | return m_window->name(); \ | | |||
2049 | } | | |||
2050 | | ||||
2051 | DELEGATE(int, width) | | |||
2052 | DELEGATE(int, height) | | |||
2053 | DELEGATE(QSize, size) | | |||
2054 | DELEGATE(QRect, geometry) | | |||
2055 | DELEGATE(WId, winId) | | |||
2056 | | ||||
2057 | #undef DELEGATE | | |||
2058 | | ||||
2059 | void CloseWindowView::setGeometry(const QRect &geometry) | | |||
2060 | { | | |||
2061 | m_posIsValid = false; | | |||
2062 | m_window->setGeometry(geometry); | | |||
2063 | } | | |||
2064 | | ||||
2065 | QPoint CloseWindowView::mapFromGlobal(const QPoint &pos) const | | |||
2066 | { | | |||
2067 | return m_window->mapFromGlobal(pos); | | |||
2068 | } | | |||
2069 | 1962 | | |||
2070 | } // namespace | 1963 | } // namespace | ||
2071 | 1964 | |
This can potentially segfault if the user unchecked "Provide buttons to close the windows" in pw kcm.