Changeset View
Changeset View
Standalone View
Standalone View
shell_client.cpp
Show First 20 Lines • Show All 348 Lines • ▼ Show 20 Line(s) | |||||
349 | } | 349 | } | ||
350 | 350 | | |||
351 | void ShellClient::finishInit() { | 351 | void ShellClient::finishInit() { | ||
352 | SurfaceInterface *s = surface(); | 352 | SurfaceInterface *s = surface(); | ||
353 | disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit); | 353 | disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit); | ||
354 | 354 | | |||
355 | updateWindowMargins(); | 355 | updateWindowMargins(); | ||
356 | 356 | | |||
357 | bool needsPlacement = !isInitialPositionSet(); | ||||
358 | | ||||
357 | if (supportsWindowRules()) { | 359 | if (supportsWindowRules()) { | ||
358 | setupWindowRules(false); | 360 | setupWindowRules(false); | ||
359 | 361 | | |||
362 | const QRect originalGeometry = QRect(pos(), sizeForClientSize(clientSize())); | ||||
363 | const QRect ruledGeometry = rules()->checkGeometry(originalGeometry, true); | ||||
364 | if (originalGeometry != ruledGeometry) { | ||||
365 | setGeometry(ruledGeometry); | ||||
366 | } | ||||
367 | | ||||
360 | setDesktop(rules()->checkDesktop(desktop(), true)); | 368 | setDesktop(rules()->checkDesktop(desktop(), true)); | ||
361 | setDesktopFileName(rules()->checkDesktopFile(desktopFileName(), true).toUtf8()); | 369 | setDesktopFileName(rules()->checkDesktopFile(desktopFileName(), true).toUtf8()); | ||
362 | if (rules()->checkMinimize(isMinimized(), true)) { | 370 | if (rules()->checkMinimize(isMinimized(), true)) { | ||
363 | minimize(true); // No animation. | 371 | minimize(true); // No animation. | ||
364 | } | 372 | } | ||
365 | setSkipTaskbar(rules()->checkSkipTaskbar(skipTaskbar(), true)); | 373 | setSkipTaskbar(rules()->checkSkipTaskbar(skipTaskbar(), true)); | ||
366 | setSkipPager(rules()->checkSkipPager(skipPager(), true)); | 374 | setSkipPager(rules()->checkSkipPager(skipPager(), true)); | ||
367 | setSkipSwitcher(rules()->checkSkipSwitcher(skipSwitcher(), true)); | 375 | setSkipSwitcher(rules()->checkSkipSwitcher(skipSwitcher(), true)); | ||
368 | setKeepAbove(rules()->checkKeepAbove(keepAbove(), true)); | 376 | setKeepAbove(rules()->checkKeepAbove(keepAbove(), true)); | ||
369 | setKeepBelow(rules()->checkKeepBelow(keepBelow(), true)); | 377 | setKeepBelow(rules()->checkKeepBelow(keepBelow(), true)); | ||
370 | setShortcut(rules()->checkShortcut(shortcut().toString(), true)); | 378 | setShortcut(rules()->checkShortcut(shortcut().toString(), true)); | ||
371 | updateColorScheme(); | 379 | updateColorScheme(); | ||
372 | 380 | | |||
381 | // Don't place the client if its position is set by a rule. | ||||
382 | if (rules()->checkPosition(invalidPoint, true) != invalidPoint) { | ||||
383 | needsPlacement = false; | ||||
384 | } | ||||
385 | | ||||
373 | discardTemporaryRules(); | 386 | discardTemporaryRules(); | ||
374 | RuleBook::self()->discardUsed(this, false); // Remove Apply Now rules. | 387 | RuleBook::self()->discardUsed(this, false); // Remove Apply Now rules. | ||
375 | updateWindowRules(Rules::All); | 388 | updateWindowRules(Rules::All); | ||
376 | } | 389 | } | ||
377 | 390 | | |||
378 | if (!isInitialPositionSet()) { | 391 | if (needsPlacement) { | ||
379 | QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); | 392 | QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop()); | ||
380 | placeIn(area); | 393 | placeIn(area); | ||
381 | } | 394 | } | ||
382 | 395 | | |||
383 | m_requestGeometryBlockCounter--; | 396 | m_requestGeometryBlockCounter--; | ||
384 | if (m_requestGeometryBlockCounter == 0) { | 397 | if (m_requestGeometryBlockCounter == 0) { | ||
385 | requestGeometry(m_blockedRequestGeometry); | 398 | requestGeometry(m_blockedRequestGeometry); | ||
386 | } | 399 | } | ||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Line(s) | 608 | { | |||
618 | getShadow(); | 631 | getShadow(); | ||
619 | if (check_workspace_pos) | 632 | if (check_workspace_pos) | ||
620 | checkWorkspacePosition(oldgeom, -2, oldClientGeom); | 633 | checkWorkspacePosition(oldgeom, -2, oldClientGeom); | ||
621 | blockGeometryUpdates(false); | 634 | blockGeometryUpdates(false); | ||
622 | } | 635 | } | ||
623 | 636 | | |||
624 | void ShellClient::setGeometry(int x, int y, int w, int h, ForceGeometry_t force) | 637 | void ShellClient::setGeometry(int x, int y, int w, int h, ForceGeometry_t force) | ||
625 | { | 638 | { | ||
639 | const QRect newGeometry = rules()->checkGeometry(QRect(x, y, w, h)); | ||||
640 | | ||||
626 | if (areGeometryUpdatesBlocked()) { | 641 | if (areGeometryUpdatesBlocked()) { | ||
627 | // when the GeometryUpdateBlocker exits the current geom is passed to setGeometry | 642 | // when the GeometryUpdateBlocker exits the current geom is passed to setGeometry | ||
628 | // thus we need to set it here. | 643 | // thus we need to set it here. | ||
629 | geom = QRect(x, y, w, h); | 644 | geom = newGeometry; | ||
630 | if (pendingGeometryUpdate() == PendingGeometryForced) | 645 | if (pendingGeometryUpdate() == PendingGeometryForced) | ||
631 | {} // maximum, nothing needed | 646 | {} // maximum, nothing needed | ||
632 | else if (force == ForceGeometrySet) | 647 | else if (force == ForceGeometrySet) | ||
633 | setPendingGeometryUpdate(PendingGeometryForced); | 648 | setPendingGeometryUpdate(PendingGeometryForced); | ||
634 | else | 649 | else | ||
635 | setPendingGeometryUpdate(PendingGeometryNormal); | 650 | setPendingGeometryUpdate(PendingGeometryNormal); | ||
636 | return; | 651 | return; | ||
637 | } | 652 | } | ||
638 | if (pendingGeometryUpdate() != PendingGeometryNone) { | 653 | if (pendingGeometryUpdate() != PendingGeometryNone) { | ||
639 | // reset geometry to the one before blocking, so that we can compare properly | 654 | // reset geometry to the one before blocking, so that we can compare properly | ||
640 | geom = geometryBeforeUpdateBlocking(); | 655 | geom = geometryBeforeUpdateBlocking(); | ||
641 | } | 656 | } | ||
642 | const QSize requestedClientSize = QSize(w, h) - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | 657 | const QSize requestedClientSize = newGeometry.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()); | ||
643 | const QSize requestedWindowGeometrySize = toWindowGeometry(QSize(w, h)); | 658 | const QSize requestedWindowGeometrySize = toWindowGeometry(newGeometry.size()); | ||
644 | 659 | | |||
645 | if (requestedClientSize == m_clientSize && !isWaitingForMoveResizeSync() && | 660 | if (requestedClientSize == m_clientSize && !isWaitingForMoveResizeSync() && | ||
646 | (m_requestedClientSize.isEmpty() || requestedWindowGeometrySize == m_requestedClientSize)) { | 661 | (m_requestedClientSize.isEmpty() || requestedWindowGeometrySize == m_requestedClientSize)) { | ||
647 | // size didn't change, and we don't need to explicitly request a new size | 662 | // size didn't change, and we don't need to explicitly request a new size | ||
648 | doSetGeometry(QRect(x, y, w, h)); | 663 | doSetGeometry(newGeometry); | ||
649 | updateMaximizeMode(m_requestedMaximizeMode); | 664 | updateMaximizeMode(m_requestedMaximizeMode); | ||
650 | } else { | 665 | } else { | ||
651 | // size did change, Client needs to provide a new buffer | 666 | // size did change, Client needs to provide a new buffer | ||
652 | requestGeometry(QRect(x, y, w, h)); | 667 | requestGeometry(newGeometry); | ||
653 | } | 668 | } | ||
654 | } | 669 | } | ||
655 | 670 | | |||
656 | void ShellClient::doSetGeometry(const QRect &rect) | 671 | void ShellClient::doSetGeometry(const QRect &rect) | ||
657 | { | 672 | { | ||
658 | if (geom == rect && pendingGeometryUpdate() == PendingGeometryNone) { | 673 | if (geom == rect && pendingGeometryUpdate() == PendingGeometryNone) { | ||
659 | return; | 674 | return; | ||
660 | } | 675 | } | ||
661 | if (!m_unmapped) { | 676 | if (!m_unmapped) { | ||
662 | addWorkspaceRepaint(visibleRect()); | 677 | addWorkspaceRepaint(visibleRect()); | ||
663 | } | 678 | } | ||
679 | | ||||
664 | geom = rect; | 680 | geom = rect; | ||
681 | updateWindowRules(Rules::Position | Rules::Size); | ||||
665 | 682 | | |||
666 | if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) { | 683 | if (m_unmapped && m_geomMaximizeRestore.isEmpty() && !geom.isEmpty()) { | ||
667 | // use first valid geometry as restore geometry | 684 | // use first valid geometry as restore geometry | ||
668 | m_geomMaximizeRestore = geom; | 685 | m_geomMaximizeRestore = geom; | ||
669 | } | 686 | } | ||
670 | 687 | | |||
671 | if (!m_unmapped) { | 688 | if (!m_unmapped) { | ||
672 | addWorkspaceRepaint(visibleRect()); | 689 | addWorkspaceRepaint(visibleRect()); | ||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | |||||
751 | 768 | | |||
752 | bool ShellClient::isFullScreen() const | 769 | bool ShellClient::isFullScreen() const | ||
753 | { | 770 | { | ||
754 | return m_fullScreen; | 771 | return m_fullScreen; | ||
755 | } | 772 | } | ||
756 | 773 | | |||
757 | bool ShellClient::isMaximizable() const | 774 | bool ShellClient::isMaximizable() const | ||
758 | { | 775 | { | ||
776 | if (!isResizable()) { | ||||
777 | return false; | ||||
778 | } | ||||
759 | return true; | 779 | return true; | ||
760 | } | 780 | } | ||
761 | 781 | | |||
762 | bool ShellClient::isMinimizable() const | 782 | bool ShellClient::isMinimizable() const | ||
763 | { | 783 | { | ||
764 | if (!rules()->checkMinimize(true)) { | 784 | if (!rules()->checkMinimize(true)) { | ||
765 | return false; | 785 | return false; | ||
766 | } | 786 | } | ||
767 | return (!m_plasmaShellSurface || m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal); | 787 | return (!m_plasmaShellSurface || m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal); | ||
768 | } | 788 | } | ||
769 | 789 | | |||
770 | bool ShellClient::isMovable() const | 790 | bool ShellClient::isMovable() const | ||
771 | { | 791 | { | ||
792 | if (rules()->checkPosition(invalidPoint) != invalidPoint) { | ||||
793 | return false; | ||||
794 | } | ||||
772 | if (m_plasmaShellSurface) { | 795 | if (m_plasmaShellSurface) { | ||
773 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | 796 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | ||
774 | } | 797 | } | ||
775 | if (m_xdgShellPopup) { | 798 | if (m_xdgShellPopup) { | ||
776 | return false; | 799 | return false; | ||
777 | } | 800 | } | ||
778 | return true; | 801 | return true; | ||
779 | } | 802 | } | ||
780 | 803 | | |||
781 | bool ShellClient::isMovableAcrossScreens() const | 804 | bool ShellClient::isMovableAcrossScreens() const | ||
782 | { | 805 | { | ||
806 | if (rules()->checkPosition(invalidPoint) != invalidPoint) { | ||||
807 | return false; | ||||
808 | } | ||||
783 | if (m_plasmaShellSurface) { | 809 | if (m_plasmaShellSurface) { | ||
784 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | 810 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | ||
785 | } | 811 | } | ||
786 | if (m_xdgShellPopup) { | 812 | if (m_xdgShellPopup) { | ||
787 | return false; | 813 | return false; | ||
788 | } | 814 | } | ||
789 | return true; | 815 | return true; | ||
790 | } | 816 | } | ||
791 | 817 | | |||
792 | bool ShellClient::isResizable() const | 818 | bool ShellClient::isResizable() const | ||
793 | { | 819 | { | ||
820 | if (rules()->checkSize(QSize()).isValid()) { | ||||
821 | return false; | ||||
822 | } | ||||
794 | if (m_plasmaShellSurface) { | 823 | if (m_plasmaShellSurface) { | ||
795 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | 824 | return m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Normal; | ||
796 | } | 825 | } | ||
797 | if (m_xdgShellPopup) { | 826 | if (m_xdgShellPopup) { | ||
798 | return false; | 827 | return false; | ||
799 | } | 828 | } | ||
800 | return true; | 829 | return true; | ||
801 | } | 830 | } | ||
Show All 32 Lines | 855 | { | |||
834 | 863 | | |||
835 | const QRect clientArea = isElectricBorderMaximizing() ? | 864 | const QRect clientArea = isElectricBorderMaximizing() ? | ||
836 | workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : | 865 | workspace()->clientArea(MaximizeArea, Cursor::pos(), desktop()) : | ||
837 | workspace()->clientArea(MaximizeArea, this); | 866 | workspace()->clientArea(MaximizeArea, this); | ||
838 | 867 | | |||
839 | const MaximizeMode oldMode = m_requestedMaximizeMode; | 868 | const MaximizeMode oldMode = m_requestedMaximizeMode; | ||
840 | const QRect oldGeometry = geometry(); | 869 | const QRect oldGeometry = geometry(); | ||
841 | 870 | | |||
842 | StackingUpdatesBlocker blocker(workspace()); | | |||
843 | RequestGeometryBlocker geometryBlocker(this); | | |||
844 | // 'adjust == true' means to update the size only, e.g. after changing workspace size | 871 | // 'adjust == true' means to update the size only, e.g. after changing workspace size | ||
845 | if (!adjust) { | 872 | if (!adjust) { | ||
846 | if (vertical) | 873 | if (vertical) | ||
847 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeVertical); | 874 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeVertical); | ||
848 | if (horizontal) | 875 | if (horizontal) | ||
849 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeHorizontal); | 876 | m_requestedMaximizeMode = MaximizeMode(m_requestedMaximizeMode ^ MaximizeHorizontal); | ||
850 | } | 877 | } | ||
851 | // TODO: add more checks as in Client | 878 | // TODO: add more checks as in Client | ||
852 | 879 | | |||
853 | if (m_requestedMaximizeMode == oldMode) { | 880 | if (m_requestedMaximizeMode == oldMode) { | ||
854 | return; | 881 | return; | ||
855 | } | 882 | } | ||
856 | 883 | | |||
884 | StackingUpdatesBlocker blocker(workspace()); | ||||
885 | RequestGeometryBlocker geometryBlocker(this); | ||||
886 | | ||||
857 | // call into decoration update borders | 887 | // call into decoration update borders | ||
858 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && m_requestedMaximizeMode == KWin::MaximizeFull)) { | 888 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && m_requestedMaximizeMode == KWin::MaximizeFull)) { | ||
859 | changeMaximizeRecursion = true; | 889 | changeMaximizeRecursion = true; | ||
860 | const auto c = decoration()->client().data(); | 890 | const auto c = decoration()->client().data(); | ||
861 | if ((m_requestedMaximizeMode & MaximizeVertical) != (oldMode & MaximizeVertical)) { | 891 | if ((m_requestedMaximizeMode & MaximizeVertical) != (oldMode & MaximizeVertical)) { | ||
862 | emit c->maximizedVerticallyChanged(m_requestedMaximizeMode & MaximizeVertical); | 892 | emit c->maximizedVerticallyChanged(m_requestedMaximizeMode & MaximizeVertical); | ||
863 | } | 893 | } | ||
864 | if ((m_requestedMaximizeMode & MaximizeHorizontal) != (oldMode & MaximizeHorizontal)) { | 894 | if ((m_requestedMaximizeMode & MaximizeHorizontal) != (oldMode & MaximizeHorizontal)) { | ||
▲ Show 20 Lines • Show All 1103 Lines • Show Last 20 Lines |