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